home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 15 / CU Amiga Magazine's Super CD-ROM 15 (1997)(EMAP Images)(GB)[!][issue 1997-10].iso / CUCD / Graphics / Ghostscript / source / libpng / pngrtran.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-05-14  |  102.1 KB  |  3,154 lines

  1.  
  2. /* pngrtran.c - transforms the data in a row for PNG readers
  3.  
  4.    libpng 1.0 beta 6 - version 0.96
  5.    For conditions of distribution and use, see copyright notice in png.h
  6.    Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
  7.    Copyright (c) 1996, 1997 Andreas Dilger
  8.    May 12, 1997
  9.    */
  10.  
  11. #define PNG_INTERNAL
  12. #include "png.h"
  13.  
  14. #ifdef PNG_READ_COMPOSITE_NODIV_SUPPORTED
  15. /* With these routines, we avoid an integer divide, which will be slower on
  16.    many machines.  However, it does take more operations than the corresponding
  17.    divide method, so it may be slower on some RISC systems.  There are two
  18.    shifts (by 8 or 16 bits) and an addition, versus a single integer divide.
  19.    The results may also be off by one for certain values. */
  20.  
  21. /* pixel and background should be in gamma 1.0 space */
  22. #define png_composite(composite, pixel, trans, background) \
  23.    { png_uint_16 temp = ((png_uint_16)(pixel) * (png_uint_16)(trans) + \
  24.                       (png_uint_16)(background)*(png_uint_16)(255 - \
  25.                       (png_uint_16)(trans)) + (png_uint_16)127); \
  26.      (composite) = (png_byte)(((temp >> 8) + temp) >> 8); }
  27.  
  28. /* pixel and background should be in gamma 1.0 space */
  29. #define png_composite_16(composite, pixel, trans, background) \
  30.    { png_uint_32 temp = ((png_uint_32)(pixel) * (png_uint_32)(trans) + \
  31.                       (png_uint_32)(background)*(png_uint_32)(65535L - \
  32.                       (png_uint_32)(trans)) + (png_uint_32)32767); \
  33.      (composite) = (png_uint_16)(((temp >> 16) + temp) >> 16); }
  34. #else
  35. /* pixel and background should be in gamma 1.0 space */
  36. #define png_composite(composite, pixel, trans, background) \
  37.    (composite) = (png_byte)(((png_uint_16)(pixel) * (png_uint_16)(trans) + \
  38.      (png_uint_16)(background) * (png_uint_16)(255 - (png_uint_16)(trans)) + \
  39.      (png_uint_16)127) / 255)
  40.  
  41. /* pixel and background should be in gamma 1.0 space */
  42. #define png_composite_16(composite, pixel, trans, background) \
  43.    (composite) = (png_uint_16)(((png_uint_32)(pixel) * (png_uint_32)(trans) + \
  44.      (png_uint_32)(background)*(png_uint_32)(65535L - (png_uint_32)(trans)) + \
  45.      (png_uint_32)32767) / 65535L)
  46. #endif
  47.  
  48. #if defined(PNG_READ_BACKGROUND_SUPPORTED)
  49. /* handle alpha and tRNS via a background color */
  50. void
  51. png_set_background(png_structp png_ptr,
  52.    png_color_16p background_color, int background_gamma_code,
  53.    int need_expand, double background_gamma)
  54. {
  55.    png_debug(1, "in png_set_background\n");
  56.    if (background_gamma_code == PNG_BACKGROUND_GAMMA_UNKNOWN)
  57.    {
  58.       png_warning(png_ptr, "Application must supply a known background gamma");
  59.       return;
  60.    }
  61.  
  62.    png_ptr->transformations |= PNG_BACKGROUND;
  63.    png_memcpy(&(png_ptr->background), background_color,
  64.       sizeof(png_color_16));
  65.    png_ptr->background_gamma = (float)background_gamma;
  66.    png_ptr->background_gamma_type = (png_byte)(background_gamma_code);
  67.    png_ptr->transformations |= (need_expand ? PNG_BACKGROUND_EXPAND : 0);
  68. }
  69. #endif
  70.  
  71. #if defined(PNG_READ_16_TO_8_SUPPORTED)
  72. /* strip 16 bit depth files to 8 bit depth */
  73. void
  74. png_set_strip_16(png_structp png_ptr)
  75. {
  76.    png_debug(1, "in png_set_strip_16\n");
  77.    png_ptr->transformations |= PNG_16_TO_8;
  78. }
  79. #endif
  80.  
  81. #if defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
  82. void
  83. png_set_strip_alpha(png_structp png_ptr)
  84. {
  85.    png_debug(1, "in png_set_strip_alpha\n");
  86.    png_ptr->transformations |= PNG_STRIP_ALPHA;
  87. }
  88. #endif
  89.  
  90. #if defined(PNG_READ_DITHER_SUPPORTED)
  91. /* Dither file to 8 bit.  Supply a palette, the current number
  92.    of elements in the palette, the maximum number of elements
  93.    allowed, and a histogram if possible.  If the current number
  94.    of colors is greater then the maximum number, the palette will be
  95.    modified to fit in the maximum number.  "full_dither" indicates
  96.    whether we need a dithering cube set up for RGB images, or if we
  97.    simply are reducing the number of colors in a paletted image. */
  98.  
  99. typedef struct png_dsort_struct
  100. {
  101.    struct png_dsort_struct FAR * next;
  102.    png_byte left;
  103.    png_byte right;
  104. } png_dsort;
  105. typedef png_dsort FAR *       png_dsortp;
  106. typedef png_dsort FAR * FAR * png_dsortpp;
  107.  
  108. void
  109. png_set_dither(png_structp png_ptr, png_colorp palette,
  110.    int num_palette, int maximum_colors, png_uint_16p histogram,
  111.    int full_dither)
  112. {
  113.    png_debug(1, "in png_set_dither\n");
  114.    png_ptr->transformations |= PNG_DITHER;
  115.  
  116.    if (!full_dither)
  117.    {
  118.       int i;
  119.  
  120.       png_ptr->dither_index = (png_bytep)png_malloc(png_ptr,
  121.          num_palette * sizeof (png_byte));
  122.       for (i = 0; i < num_palette; i++)
  123.          png_ptr->dither_index[i] = (png_byte)i;
  124.    }
  125.  
  126.    if (num_palette > maximum_colors)
  127.    {
  128.       if (histogram != NULL)
  129.       {
  130.          /* This is easy enough, just throw out the least used colors.
  131.             Perhaps not the best solution, but good enough. */
  132.  
  133.          int i;
  134.          png_bytep sort;
  135.  
  136.          /* initialize an array to sort colors */
  137.          sort = (png_bytep)png_malloc(png_ptr, num_palette * sizeof (png_byte));
  138.  
  139.          /* initialize the sort array */
  140.          for (i = 0; i < num_palette; i++)
  141.             sort[i] = (png_byte)i;
  142.  
  143.          /* Find the least used palette entries by starting a
  144.             bubble sort, and running it until we have sorted
  145.             out enough colors.  Note that we don't care about
  146.             sorting all the colors, just finding which are
  147.             least used. */
  148.  
  149.          for (i = num_palette - 1; i >= maximum_colors; i--)
  150.          {
  151.             int done; /* to stop early if the list is pre-sorted */
  152.             int j;
  153.  
  154.             done = 1;
  155.             for (j = 0; j < i; j++)
  156.             {
  157.                if (histogram[sort[j]] < histogram[sort[j + 1]])
  158.                {
  159.                   png_byte t;
  160.  
  161.                   t = sort[j];
  162.                   sort[j] = sort[j + 1];
  163.                   sort[j + 1] = t;
  164.                   done = 0;
  165.                }
  166.             }
  167.             if (done)
  168.                break;
  169.          }
  170.  
  171.          /* swap the palette around, and set up a table, if necessary */
  172.          if (full_dither)
  173.          {
  174.             int j;
  175.  
  176.             /* put all the useful colors within the max, but don't
  177.                move the others */
  178.             for (i = 0, j = num_palette; i < maximum_colors; i++)
  179.             {
  180.                if (sort[i] >= maximum_colors)
  181.                {
  182.                   do
  183.                      j--;
  184.                   while (sort[j] >= maximum_colors);
  185.                   palette[i] = palette[j];
  186.                }
  187.             }
  188.          }
  189.          else
  190.          {
  191.             int j;
  192.  
  193.             /* move all the used colors inside the max limit, and
  194.                develop a translation table */
  195.             for (i = 0, j = num_palette; i < maximum_colors; i++)
  196.             {
  197.                /* only move the colors we need to */
  198.                if (sort[i] >= maximum_colors)
  199.                {
  200.                   png_color tmp_color;
  201.  
  202.                   do
  203.                      j--;
  204.                   while (sort[j] >= maximum_colors);
  205.  
  206.                   tmp_color = palette[j];
  207.                   palette[j] = palette[i];
  208.                   palette[i] = tmp_color;
  209.                   /* indicate where the color went */
  210.                   png_ptr->dither_index[j] = (png_byte)i;
  211.                   png_ptr->dither_index[i] = (png_byte)j;
  212.                }
  213.             }
  214.  
  215.             /* find closest color for those colors we are not using */
  216.             for (i = 0; i < num_palette; i++)
  217.             {
  218.                if (png_ptr->dither_index[i] >= maximum_colors)
  219.                {
  220.                   int min_d, k, min_k, d_index;
  221.  
  222.                   /* find the closest color to one we threw out */
  223.                   d_index = png_ptr->dither_index[i];
  224.                   min_d = PNG_COLOR_DIST(palette[d_index], palette[0]);
  225.                   for (k = 1, min_k = 0; k < maximum_colors; k++)
  226.                   {
  227.                      int d;
  228.  
  229.                      d = PNG_COLOR_DIST(palette[d_index], palette[k]);
  230.  
  231.                      if (d < min_d)
  232.                      {
  233.                         min_d = d;
  234.                         min_k = k;
  235.                      }
  236.                   }
  237.                   /* point to closest color */
  238.                   png_ptr->dither_index[i] = (png_byte)min_k;
  239.                }
  240.             }
  241.          }
  242.          png_free(png_ptr, sort);
  243.       }
  244.       else
  245.       {
  246.          /* This is much harder to do simply (and quickly).  Perhaps
  247.             we need to go through a median cut routine, but those
  248.             don't always behave themselves with only a few colors
  249.             as input.  So we will just find the closest two colors,
  250.             and throw out one of them (chosen somewhat randomly).
  251.             [I don't understand this at all, so if someone wants to
  252.              work on improving it, be my guest - AED]
  253.             */
  254.          int i;
  255.          int max_d;
  256.          int num_new_palette;
  257.          png_dsortpp hash;
  258.          png_bytep index_to_palette;
  259.             /* where the original index currently is in the palette */
  260.          png_bytep palette_to_index;
  261.             /* which original index points to this palette color */
  262.  
  263.          /* initialize palette index arrays */
  264.          index_to_palette = (png_bytep)png_malloc(png_ptr,
  265.             num_palette * sizeof (png_byte));
  266.          palette_to_index = (png_bytep)png_malloc(png_ptr,
  267.             num_palette * sizeof (png_byte));
  268.  
  269.          /* initialize the sort array */
  270.          for (i = 0; i < num_palette; i++)
  271.          {
  272.             index_to_palette[i] = (png_byte)i;
  273.             palette_to_index[i] = (png_byte)i;
  274.          }
  275.  
  276.          hash = (png_dsortpp)png_malloc(png_ptr, 769 * sizeof (png_dsortp));
  277.          for (i = 0; i < 769; i++)
  278.             hash[i] = NULL;
  279. /*         png_memset(hash, 0, 769 * sizeof (png_dsortp)); */
  280.  
  281.          num_new_palette = num_palette;
  282.  
  283.          /* initial wild guess at how far apart the farthest pixel
  284.             pair we will be eliminating will be.  Larger
  285.             numbers mean more areas will be allocated, Smaller
  286.             numbers run the risk of not saving enough data, and
  287.             having to do this all over again.
  288.  
  289.             I have not done extensive checking on this number.
  290.             */
  291.          max_d = 96;
  292.  
  293.          while (num_new_palette > maximum_colors)
  294.          {
  295.             for (i = 0; i < num_new_palette - 1; i++)
  296.             {
  297.                int j;
  298.  
  299.                for (j = i + 1; j < num_new_palette; j++)
  300.                {
  301.                   int d;
  302.  
  303.                   d = PNG_COLOR_DIST(palette[i], palette[j]);
  304.  
  305.                   if (d <= max_d)
  306.                   {
  307.                      png_dsortp t;
  308.  
  309.                      t = png_malloc(png_ptr, sizeof (png_dsort));
  310.                      t->next = hash[d];
  311.                      t->left = (png_byte)i;
  312.                      t->right = (png_byte)j;
  313.                      hash[d] = t;
  314.                   }
  315.                }
  316.             }
  317.  
  318.             for (i = 0; i <= max_d; i++)
  319.             {
  320.                if (hash[i] != NULL)
  321.                {
  322.                   png_dsortp p;
  323.  
  324.                   for (p = hash[i]; p; p = p->next)
  325.                   {
  326.                      if (index_to_palette[p->left] < num_new_palette &&
  327.                         index_to_palette[p->right] < num_new_palette)
  328.                      {
  329.                         int j, next_j;
  330.  
  331.                         if (num_new_palette & 1)
  332.                         {
  333.                            j = p->left;
  334.                            next_j = p->right;
  335.                         }
  336.                         else
  337.                         {
  338.                            j = p->right;
  339.                            next_j = p->left;
  340.                         }
  341.  
  342.                         num_new_palette--;
  343.                         palette[index_to_palette[j]] = palette[num_new_palette];
  344.                         if (!full_dither)
  345.                         {
  346.                            int k;
  347.  
  348.                            for (k = 0; k < num_palette; k++)
  349.                            {
  350.                               if (png_ptr->dither_index[k] ==
  351.                                  index_to_palette[j])
  352.                                  png_ptr->dither_index[k] =
  353.                                     index_to_palette[next_j];
  354.                               if (png_ptr->dither_index[k] ==
  355.                                  num_new_palette)
  356.                                  png_ptr->dither_index[k] =
  357.                                     index_to_palette[j];
  358.                            }
  359.                         }
  360.  
  361.                         index_to_palette[palette_to_index[num_new_palette]] =
  362.                            index_to_palette[j];
  363.                         palette_to_index[index_to_palette[j]] =
  364.                            palette_to_index[num_new_palette];
  365.  
  366.                         index_to_palette[j] = (png_byte)num_new_palette;
  367.                         palette_to_index[num_new_palette] = (png_byte)j;
  368.                      }
  369.                      if (num_new_palette <= maximum_colors)
  370.                         break;
  371.                   }
  372.                   if (num_new_palette <= maximum_colors)
  373.                      break;
  374.                }
  375.             }
  376.  
  377.             for (i = 0; i < 769; i++)
  378.             {
  379.                if (hash[i] != NULL)
  380.                {
  381.                   png_dsortp p;
  382.  
  383.                   p = hash[i];
  384.                   while (p)
  385.                   {
  386.                      png_dsortp t;
  387.  
  388.                      t = p->next;
  389.                      png_free(png_ptr, p);
  390.                      p = t;
  391.                   }
  392.                }
  393.                hash[i] = 0;
  394.             }
  395.             max_d += 96;
  396.          }
  397.          png_free(png_ptr, hash);
  398.          png_free(png_ptr, palette_to_index);
  399.          png_free(png_ptr, index_to_palette);
  400.       }
  401.       num_palette = maximum_colors;
  402.    }
  403.    if (png_ptr->palette == NULL)
  404.    {
  405.       png_ptr->palette = palette;
  406.    }
  407.    png_ptr->num_palette = (png_uint_16)num_palette;
  408.  
  409.    if (full_dither)
  410.    {
  411.       int i;
  412.       int total_bits, num_red, num_green, num_blue;
  413.       png_size_t num_entries;
  414.       png_bytep distance;
  415.  
  416.       total_bits = PNG_DITHER_RED_BITS + PNG_DITHER_GREEN_BITS +
  417.          PNG_DITHER_BLUE_BITS;
  418.  
  419.       num_red = (1 << PNG_DITHER_RED_BITS);
  420.       num_green = (1 << PNG_DITHER_GREEN_BITS);
  421.       num_blue = (1 << PNG_DITHER_BLUE_BITS);
  422.       num_entries = ((png_size_t)1 << total_bits);
  423.  
  424.       png_ptr->palette_lookup = (png_bytep )png_malloc(png_ptr,
  425.          num_entries * sizeof (png_byte));
  426.  
  427.       png_memset(png_ptr->palette_lookup, 0, num_entries * sizeof (png_byte));
  428.  
  429.       distance = (png_bytep)png_malloc(png_ptr, num_entries * sizeof(png_byte));
  430.  
  431.       png_memset(distance, 0xff, num_entries * sizeof(png_byte));
  432.  
  433.       for (i = 0; i < num_palette; i++)
  434.       {
  435.          int r, g, b, ir, ig, ib;
  436.  
  437.          r = (palette[i].red >> (8 - PNG_DITHER_RED_BITS));
  438.          g = (palette[i].green >> (8 - PNG_DITHER_GREEN_BITS));
  439.          b = (palette[i].blue >> (8 - PNG_DITHER_BLUE_BITS));
  440.  
  441.          for (ir = 0; ir < num_red; ir++)
  442.          {
  443.             int dr, index_r;
  444.  
  445.             dr = abs(ir - r);
  446.             index_r = (ir << (PNG_DITHER_BLUE_BITS + PNG_DITHER_GREEN_BITS));
  447.             for (ig = 0; ig < num_green; ig++)
  448.             {
  449.                int dg, dt, dm, index_g;
  450.  
  451.                dg = abs(ig - g);
  452.                dt = dr + dg;
  453.                dm = ((dr > dg) ? dr : dg);
  454.                index_g = index_r | (ig << PNG_DITHER_BLUE_BITS);
  455.                for (ib = 0; ib < num_blue; ib++)
  456.                {
  457.                   int d_index, db, dmax, d;
  458.  
  459.                   d_index = index_g | ib;
  460.                   db = abs(ib - b);
  461.                   dmax = ((dm > db) ? dm : db);
  462.                   d = dmax + dt + db;
  463.  
  464.                   if (d < distance[d_index])
  465.                   {
  466.                      distance[d_index] = (png_byte)d;
  467.                      png_ptr->palette_lookup[d_index] = (png_byte)i;
  468.                   }
  469.                }
  470.             }
  471.          }
  472.       }
  473.  
  474.       png_free(png_ptr, distance);
  475.    }
  476. }
  477. #endif
  478.  
  479. #if defined(PNG_READ_GAMMA_SUPPORTED)
  480. /* Transform the image from the file_gamma to the screen_gamma.  We
  481.    only do transformations on images where the file_gamma and screen_gamma
  482.    are not close reciprocals, otherwise it slows things down slightly, and
  483.    also needlessly introduces small errors. */
  484. void
  485. png_set_gamma(png_structp png_ptr, double screen_gamma, double file_gamma)
  486. {
  487.    png_debug(1, "in png_set_gamma\n");
  488.    if (fabs(screen_gamma * file_gamma - 1.0) > PNG_GAMMA_THRESHOLD)
  489.       png_ptr->transformations |= PNG_GAMMA;
  490.    png_ptr->gamma = (float)file_gamma;
  491.    png_ptr->display_gamma = (float)screen_gamma;
  492. }
  493. #endif
  494.  
  495. #if defined(PNG_READ_EXPAND_SUPPORTED)
  496. /* Expand paletted images to rgb, expand grayscale images of
  497.    less then 8 bit depth to 8 bit depth, and expand tRNS chunks
  498.    to alpha channels. */
  499. void
  500. png_set_expand(png_structp png_ptr)
  501. {
  502.    png_debug(1, "in png_set_expand\n");
  503.    png_ptr->transformations |= PNG_EXPAND;
  504. }
  505. #endif
  506.  
  507. #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
  508. void
  509. png_set_gray_to_rgb(png_structp png_ptr)
  510. {
  511.    png_debug(1, "in png_set_gray_to_rgb\n");
  512.    png_ptr->transformations |= PNG_GRAY_TO_RGB;
  513. }
  514. #endif
  515.  
  516. #if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
  517. /* Convert a RGB image to a grayscale of the given width.  This would
  518.    allow us, for example, to convert a 24 bpp RGB image into an 8 or
  519.    16 bpp grayscale image. (Not yet implemented.) */
  520. void
  521. png_set_rgb_to_gray(png_structp png_ptr, int gray_bits)
  522. {
  523.    png_debug(1, "in png_set_rgb_to_gray\n");
  524.    png_ptr->transformations |= PNG_RGB_TO_GRAY;
  525.    /* Need to do something with gray_bits here. */
  526. }
  527. #endif
  528.  
  529. /* Initialize everything needed for the read.  This includes modifying
  530.    the palette */
  531. void
  532. png_init_read_transformations(png_structp png_ptr)
  533. {
  534.    int color_type;
  535.  
  536.    png_debug(1, "in png_init_read_transformations\n");
  537.    color_type = png_ptr->color_type;
  538.  
  539. #if defined(PNG_READ_EXPAND_SUPPORTED) && defined(PNG_READ_BACKGROUND_SUPPORTED)
  540.    if (png_ptr->transformations & PNG_BACKGROUND_EXPAND)
  541.    {
  542.       if (color_type == PNG_COLOR_TYPE_GRAY)
  543.       {
  544.          /* expand background chunk. */
  545.          switch (png_ptr->bit_depth)
  546.          {
  547.             case 1:
  548.                png_ptr->background.gray *= (png_uint_16)0xff;
  549.                png_ptr->background.red = png_ptr->background.green =
  550.                png_ptr->background.blue = png_ptr->background.gray;
  551.                break;
  552.             case 2:
  553.                png_ptr->background.gray *= (png_uint_16)0x55;
  554.                png_ptr->background.red = png_ptr->background.green =
  555.                png_ptr->background.blue = png_ptr->background.gray;
  556.                break;
  557.             case 4:
  558.                png_ptr->background.gray *= (png_uint_16)0x11;
  559.                png_ptr->background.red = png_ptr->background.green =
  560.                png_ptr->background.blue = png_ptr->background.gray;
  561.                break;
  562.             case 8:
  563.             case 16:
  564.                png_ptr->background.red = png_ptr->background.green =
  565.                png_ptr->background.blue = png_ptr->background.gray;
  566.                break;
  567.          }
  568.       }
  569.       else if (color_type == PNG_COLOR_TYPE_PALETTE)
  570.       {
  571.          png_ptr->background.red   =
  572.             png_ptr->palette[png_ptr->background.index].red;
  573.          png_ptr->background.green =
  574.             png_ptr->palette[png_ptr->background.index].green;
  575.          png_ptr->background.blue  =
  576.             png_ptr->palette[png_ptr->background.index].blue;
  577.       }
  578.    }
  579. #endif
  580.  
  581. #if defined(PNG_READ_BACKGROUND_SUPPORTED)
  582.    png_ptr->background_1 = png_ptr->background;
  583. #endif
  584. #if defined(PNG_READ_GAMMA_SUPPORTED)
  585.    if (png_ptr->transformations & PNG_GAMMA)
  586.    {
  587.       png_build_gamma_table(png_ptr);
  588. #if defined(PNG_READ_BACKGROUND_SUPPORTED)
  589.       if (png_ptr->transformations & PNG_BACKGROUND)
  590.       {
  591.          if (color_type == PNG_COLOR_TYPE_PALETTE)
  592.          {
  593.             int num_palette, i;
  594.             png_color back, back_1;
  595.             png_colorp palette;
  596.  
  597.             palette = png_ptr->palette;
  598.             num_palette = png_ptr->num_palette;
  599.  
  600.             if (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_FILE)
  601.             {
  602.                back.red = png_ptr->gamma_table[png_ptr->background.red];
  603.                back.green = png_ptr->gamma_table[png_ptr->background.green];
  604.                back.blue = png_ptr->gamma_table[png_ptr->background.blue];
  605.  
  606.                back_1.red = png_ptr->gamma_to_1[png_ptr->background.red];
  607.                back_1.green = png_ptr->gamma_to_1[png_ptr->background.green];
  608.                back_1.blue = png_ptr->gamma_to_1[png_ptr->background.blue];
  609.             }
  610.             else
  611.             {
  612.                double g;
  613.  
  614.                g = 1.0 / (png_ptr->background_gamma * png_ptr->display_gamma);
  615.  
  616.                if (png_ptr->background_gamma_type==PNG_BACKGROUND_GAMMA_SCREEN||
  617.                    fabs(g - 1.0) < PNG_GAMMA_THRESHOLD)
  618.                {
  619.                   back.red = (png_byte)png_ptr->background.red;
  620.                   back.green = (png_byte)png_ptr->background.green;
  621.                   back.blue = (png_byte)png_ptr->background.blue;
  622.                }
  623.                else
  624.                {
  625.                   back.red =
  626.                      (png_byte)(pow((double)png_ptr->background.red/255, g) *
  627.                       255.0 + 0.5);
  628.                   back.green =
  629.                      (png_byte)(pow((double)png_ptr->background.green/255, g) *
  630.                       255.0 + 0.5);
  631.                   back.blue =
  632.                      (png_byte)(pow((double)png_ptr->background.blue/255, g) *
  633.                       255.0 + 0.5);
  634.                }
  635.  
  636.                g = 1.0 / png_ptr->background_gamma;
  637.  
  638.                back_1.red =
  639.                   (png_byte)(pow((double)png_ptr->background.red/255, g) *
  640.                    255.0 + 0.5);
  641.                back_1.green =
  642.                   (png_byte)(pow((double)png_ptr->background.green/255, g) *
  643.                    255.0 + 0.5);
  644.                back_1.blue =
  645.                   (png_byte)(pow((double)png_ptr->background.blue/255, g) *
  646.                    255.0 + 0.5);
  647.             }
  648.  
  649.             for (i = 0; i < num_palette; i++)
  650.             {
  651.                if (i < (int)png_ptr->num_trans && png_ptr->trans[i] != 0xff)
  652.                {
  653.                   if (png_ptr->trans[i] == 0)
  654.                   {
  655.                      palette[i] = back;
  656.                   }
  657.                   else /* if (png_ptr->trans[i] != 0xff) */
  658.                   {
  659.                      png_byte v, w;
  660.  
  661.                      v = png_ptr->gamma_to_1[palette[i].red];
  662.                      png_composite(w, v, png_ptr->trans[i], back_1.red);
  663.                      palette[i].red = png_ptr->gamma_from_1[w];
  664.  
  665.                      v = png_ptr->gamma_to_1[palette[i].green];
  666.                      png_composite(w, v, png_ptr->trans[i], back_1.green);
  667.                      palette[i].green = png_ptr->gamma_from_1[w];
  668.  
  669.                      v = png_ptr->gamma_to_1[palette[i].blue];
  670.                      png_composite(w, v, png_ptr->trans[i], back_1.blue);
  671.                      palette[i].blue = png_ptr->gamma_from_1[w];
  672.                   }
  673.                }
  674.                else
  675.                {
  676.                   palette[i].red = png_ptr->gamma_table[palette[i].red];
  677.                   palette[i].green = png_ptr->gamma_table[palette[i].green];
  678.                   palette[i].blue = png_ptr->gamma_table[palette[i].blue];
  679.                }
  680.             }
  681.          }
  682.          else
  683.          /* if (png_ptr->background_gamma_type!=PNG_BACKGROUND_GAMMA_UNKNOWN)*/
  684.          {
  685.             double g, gs, m;
  686.  
  687.             m = (double)(((png_uint_32)1 << png_ptr->bit_depth) - 1);
  688.             g = 1.0;
  689.             gs = 1.0;
  690.  
  691.             switch (png_ptr->background_gamma_type)
  692.             {
  693.                case PNG_BACKGROUND_GAMMA_SCREEN:
  694.                   g = (png_ptr->display_gamma);
  695.                   gs = 1.0;
  696.                   break;
  697.                case PNG_BACKGROUND_GAMMA_FILE:
  698.                   g = 1.0 / (png_ptr->gamma);
  699.                   gs = 1.0 / (png_ptr->gamma * png_ptr->display_gamma);
  700.                   break;
  701.                case PNG_BACKGROUND_GAMMA_UNIQUE:
  702.                   g = 1.0 / (png_ptr->background_gamma);
  703.                   gs = 1.0 / (png_ptr->background_gamma *
  704.                      png_ptr->display_gamma);
  705.                   break;
  706.             }
  707.  
  708.             if (color_type & PNG_COLOR_MASK_COLOR)
  709.             {
  710.                png_ptr->background_1.red = (png_uint_16)(pow(
  711.                   (double)png_ptr->background.red / m, g) * m + .5);
  712.                png_ptr->background_1.green = (png_uint_16)(pow(
  713.                   (double)png_ptr->background.green / m, g) * m + .5);
  714.                png_ptr->background_1.blue = (png_uint_16)(pow(
  715.                   (double)png_ptr->background.blue / m, g) * m + .5);
  716.                png_ptr->background.red = (png_uint_16)(pow(
  717.                   (double)png_ptr->background.red / m, gs) * m + .5);
  718.                png_ptr->background.green = (png_uint_16)(pow(
  719.                   (double)png_ptr->background.green / m, gs) * m + .5);
  720.                png_ptr->background.blue = (png_uint_16)(pow(
  721.                   (double)png_ptr->background.blue / m, gs) * m + .5);
  722.             }
  723.             else
  724.             {
  725.                png_ptr->background_1.gray = (png_uint_16)(pow(
  726.                   (double)png_ptr->background.gray / m, g) * m + .5);
  727.                png_ptr->background.gray = (png_uint_16)(pow(
  728.                   (double)png_ptr->background.gray / m, gs) * m + .5);
  729.             }
  730.          }
  731.       }
  732.       else
  733. #endif
  734.       if (color_type == PNG_COLOR_TYPE_PALETTE)
  735.       {
  736.          int num_palette, i;
  737.          png_colorp palette;
  738.  
  739.          palette = png_ptr->palette;
  740.          num_palette = png_ptr->num_palette;
  741.  
  742.          for (i = 0; i < num_palette; i++)
  743.          {
  744.             palette[i].red = png_ptr->gamma_table[palette[i].red];
  745.             palette[i].green = png_ptr->gamma_table[palette[i].green];
  746.             palette[i].blue = png_ptr->gamma_table[palette[i].blue];
  747.          }
  748.       }
  749.    }
  750. #if defined(PNG_READ_BACKGROUND_SUPPORTED)
  751.    else
  752. #endif
  753. #endif
  754. #if defined(PNG_READ_BACKGROUND_SUPPORTED)
  755.    if (png_ptr->transformations & PNG_BACKGROUND &&
  756.        color_type == PNG_COLOR_TYPE_PALETTE)
  757.    {
  758.       int i;
  759.       png_color back;
  760.       png_colorp palette;
  761.  
  762.       palette = png_ptr->palette;
  763.       back.red   = (png_byte)png_ptr->background.red;
  764.       back.green = (png_byte)png_ptr->background.green;
  765.       back.blue  = (png_byte)png_ptr->background.blue;
  766.  
  767.       for (i = 0; i < png_ptr->num_trans; i++)
  768.       {
  769.          if (png_ptr->trans[i] == 0)
  770.          {
  771.             palette[i] = back;
  772.          }
  773.          else if (png_ptr->trans[i] != 0xff)
  774.          {
  775.             png_composite(palette[i].red, palette[i].red,
  776.                png_ptr->trans[i], back.red);
  777.             png_composite(palette[i].green, palette[i].green,
  778.                png_ptr->trans[i], back.green);
  779.             png_composite(palette[i].blue, palette[i].blue,
  780.                png_ptr->trans[i], back.blue);
  781.          }
  782.       }
  783.    }
  784. #endif
  785.  
  786. #if defined(PNG_READ_SHIFT_SUPPORTED)
  787.    if ((png_ptr->transformations & PNG_SHIFT) &&
  788.       color_type == PNG_COLOR_TYPE_PALETTE)
  789.    {
  790.       png_uint_16 i;
  791.       int sr, sg, sb;
  792.  
  793.       sr = 8 - png_ptr->sig_bit.red;
  794.       if (sr < 0 || sr > 8)
  795.          sr = 0;
  796.       sg = 8 - png_ptr->sig_bit.green;
  797.       if (sg < 0 || sg > 8)
  798.          sg = 0;
  799.       sb = 8 - png_ptr->sig_bit.blue;
  800.       if (sb < 0 || sb > 8)
  801.          sb = 0;
  802.       for (i = 0; i < png_ptr->num_palette; i++)
  803.       {
  804.          png_ptr->palette[i].red >>= sr;
  805.          png_ptr->palette[i].green >>= sg;
  806.          png_ptr->palette[i].blue >>= sb;
  807.       }
  808.    }
  809. #endif
  810. }
  811.  
  812. /* Modify the info structure to reflect the transformations.  The
  813.    info should be updated so a PNG file could be written with it,
  814.    assuming the transformations result in valid PNG data. */
  815. void
  816. png_read_transform_info(png_structp png_ptr, png_infop info_ptr)
  817. {
  818.    png_debug(1, "in png_read_transform_info\n");
  819. #if defined(PNG_READ_EXPAND_SUPPORTED)
  820.    if (png_ptr->transformations & PNG_EXPAND)
  821.    {
  822.       if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
  823.       {
  824.          if (png_ptr->num_trans)
  825.             info_ptr->color_type = PNG_COLOR_TYPE_RGB_ALPHA;
  826.          else
  827.             info_ptr->color_type = PNG_COLOR_TYPE_RGB;
  828.          info_ptr->bit_depth = 8;
  829.          info_ptr->num_trans = 0;
  830.       }
  831.       else
  832.       {
  833.          if (png_ptr->num_trans)
  834.             info_ptr->color_type |= PNG_COLOR_MASK_ALPHA;
  835.          if (info_ptr->bit_depth < 8)
  836.             info_ptr->bit_depth = 8;
  837.          info_ptr->num_trans = 0;
  838.       }
  839.    }
  840. #endif
  841.  
  842. #if defined(PNG_READ_BACKGROUND_SUPPORTED)
  843.    if (png_ptr->transformations & PNG_BACKGROUND)
  844.    {
  845.       info_ptr->color_type &= ~PNG_COLOR_MASK_ALPHA;
  846.       info_ptr->num_trans = 0;
  847.       info_ptr->background = png_ptr->background;
  848.    }
  849. #endif
  850.  
  851. #if defined(PNG_READ_16_TO_8_SUPPORTED)
  852.    if ((png_ptr->transformations & PNG_16_TO_8) && info_ptr->bit_depth == 16)
  853.       info_ptr->bit_depth = 8;
  854. #endif
  855.  
  856. #if defined(PNG_READ_DITHER_SUPPORTED)
  857.    if (png_ptr->transformations & PNG_DITHER)
  858.    {
  859.       if (((info_ptr->color_type == PNG_COLOR_TYPE_RGB) ||
  860.          (info_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)) &&
  861.          png_ptr->palette_lookup && info_ptr->bit_depth == 8)
  862.       {
  863.          info_ptr->color_type = PNG_COLOR_TYPE_PALETTE;
  864.       }
  865.    }
  866. #endif
  867.  
  868. #if defined(PNG_READ_PACK_SUPPORTED)
  869.    if ((png_ptr->transformations & PNG_PACK) && info_ptr->bit_depth < 8)
  870.       info_ptr->bit_depth = 8;
  871. #endif
  872.  
  873. #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
  874.    if ((png_ptr->transformations & PNG_GRAY_TO_RGB) &&
  875.       !(info_ptr->color_type & PNG_COLOR_MASK_COLOR))
  876.       info_ptr->color_type |= PNG_COLOR_MASK_COLOR;
  877. #endif
  878.  
  879.    if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
  880.       info_ptr->channels = 1;
  881.    else if (info_ptr->color_type & PNG_COLOR_MASK_COLOR)
  882.       info_ptr->channels = 3;
  883.    else
  884.       info_ptr->channels = 1;
  885.  
  886. #if defined(PNG_STRIP_ALPHA_SUPPORTED)
  887.    if ((png_ptr->transformations & PNG_STRIP_ALPHA) &&
  888.        info_ptr->color_type & PNG_COLOR_MASK_ALPHA)
  889.    {
  890.       info_ptr->channels--;
  891.       info_ptr->color_type &= ~PNG_COLOR_MASK_ALPHA;
  892.    }
  893. #endif
  894.  
  895. #if defined(PNG_READ_FILLER_SUPPORTED)
  896.    if ((png_ptr->transformations & PNG_FILLER) &&
  897.        info_ptr->color_type & PNG_COLOR_TYPE_RGB &&
  898.        info_ptr->channels == 3)
  899.    {
  900.       info_ptr->channels = 4;
  901.    }
  902. #endif
  903.  
  904.    if (info_ptr->color_type & PNG_COLOR_MASK_ALPHA)
  905.       info_ptr->channels++;
  906.    info_ptr->pixel_depth = (png_byte)(info_ptr->channels *
  907.       info_ptr->bit_depth);
  908.  
  909.    info_ptr->rowbytes = 
  910.       (png_size_t)((info_ptr->width * info_ptr->pixel_depth + 7) >> 3);
  911. }
  912.  
  913. /* transform the row.  The order of transformations is significant,
  914.    and is very touchy.  If you add a transformation, take care to
  915.    decide how it fits in with the other transformations here. */
  916. void
  917. png_do_read_transformations(png_structp png_ptr)
  918. {
  919.    png_debug(1, "in png_do_read_transformations\n");
  920. #if !defined(PNG_USELESS_TESTS_SUPPORTED)
  921.    if (png_ptr->row_buf == NULL)
  922.    {
  923.       char msg[50];
  924.  
  925.       sprintf(msg, "NULL row buffer for row %ld, pass %d", png_ptr->row_number,
  926.          png_ptr->pass);
  927.       png_error(png_ptr, msg);
  928.    }
  929. #endif
  930.  
  931. #if defined(PNG_READ_EXPAND_SUPPORTED)
  932.    if (png_ptr->transformations & PNG_EXPAND)
  933.    {
  934.       if (png_ptr->row_info.color_type == PNG_COLOR_TYPE_PALETTE)
  935.       {
  936.          png_do_expand_palette(&(png_ptr->row_info), png_ptr->row_buf + 1,
  937.             png_ptr->palette, png_ptr->trans, png_ptr->num_trans);
  938.       }
  939.       else if (png_ptr->transformations & PNG_EXPAND)
  940.       {
  941.          if (png_ptr->num_trans)
  942.             png_do_expand(&(png_ptr->row_info), png_ptr->row_buf + 1,
  943.                &(png_ptr->trans_values));
  944.          else
  945.             png_do_expand(&(png_ptr->row_info), png_ptr->row_buf + 1,
  946.                NULL);
  947.       }
  948.    }
  949. #endif
  950.  
  951. #if defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
  952.    if (png_ptr->transformations & PNG_STRIP_ALPHA)
  953.       png_do_strip_filler(&(png_ptr->row_info), png_ptr->row_buf + 1,
  954.          PNG_FLAG_FILLER_AFTER);
  955. #endif
  956.  
  957. #if defined(PNG_READ_BACKGROUND_SUPPORTED)
  958.    if (png_ptr->transformations & PNG_BACKGROUND)
  959.       png_do_background(&(png_ptr->row_info), png_ptr->row_buf + 1,
  960.          &(png_ptr->trans_values), &(png_ptr->background),
  961.          &(png_ptr->background_1),
  962.          png_ptr->gamma_table, png_ptr->gamma_from_1,
  963.          png_ptr->gamma_to_1, png_ptr->gamma_16_table,
  964.          png_ptr->gamma_16_from_1, png_ptr->gamma_16_to_1,
  965.          png_ptr->gamma_shift);
  966. #endif
  967.  
  968. #if defined(PNG_READ_GAMMA_SUPPORTED)
  969.    if ((png_ptr->transformations & PNG_GAMMA) &&
  970.       !(png_ptr->transformations & PNG_BACKGROUND) &&
  971.       (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE))
  972.       png_do_gamma(&(png_ptr->row_info), png_ptr->row_buf + 1,
  973.          png_ptr->gamma_table, png_ptr->gamma_16_table,
  974.          png_ptr->gamma_shift);
  975. #endif
  976.  
  977. #if defined(PNG_RGB_TO_GRAY_SUPPORTED)
  978.    if (png_ptr->transformations & PNG_RGB_TO_GRAY)
  979.       png_do_rgb_to_gray(&(png_ptr->row_info), png_ptr->row_buf + 1);
  980. #endif
  981.  
  982. #if defined(PNG_READ_16_TO_8_SUPPORTED)
  983.    if (png_ptr->transformations & PNG_16_TO_8)
  984.       png_do_chop(&(png_ptr->row_info), png_ptr->row_buf + 1);
  985. #endif
  986.  
  987. #if defined(PNG_READ_DITHER_SUPPORTED)
  988.    if (png_ptr->transformations & PNG_DITHER)
  989.    {
  990.       png_do_dither((png_row_infop)&(png_ptr->row_info), png_ptr->row_buf + 1,
  991.          png_ptr->palette_lookup, png_ptr->dither_index);
  992.    }
  993. #endif
  994.  
  995. #if defined(PNG_READ_INVERT_SUPPORTED)
  996.    if (png_ptr->transformations & PNG_INVERT_MONO)
  997.       png_do_invert(&(png_ptr->row_info), png_ptr->row_buf + 1);
  998. #endif
  999.  
  1000. #if defined(PNG_READ_SHIFT_SUPPORTED)
  1001.    if (png_ptr->transformations & PNG_SHIFT)
  1002.       png_do_unshift(&(png_ptr->row_info), png_ptr->row_buf + 1,
  1003.          &(png_ptr->shift));
  1004. #endif
  1005.  
  1006. #if defined(PNG_READ_PACK_SUPPORTED)
  1007.    if (png_ptr->transformations & PNG_PACK)
  1008.       png_do_unpack(&(png_ptr->row_info), png_ptr->row_buf + 1);
  1009. #endif
  1010.  
  1011. #if defined(PNG_READ_BGR_SUPPORTED)
  1012.    if (png_ptr->transformations & PNG_BGR)
  1013.       png_do_bgr(&(png_ptr->row_info), png_ptr->row_buf + 1);
  1014. #endif
  1015.  
  1016. #if defined(PNG_READ_PACKSWAP_SUPPORTED)
  1017.    if (png_ptr->transformations & PNG_PACKSWAP)
  1018.       png_do_packswap(&(png_ptr->row_info), png_ptr->row_buf + 1);
  1019. #endif
  1020.  
  1021. #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
  1022.    if (png_ptr->transformations & PNG_GRAY_TO_RGB)
  1023.       png_do_gray_to_rgb(&(png_ptr->row_info), png_ptr->row_buf + 1);
  1024. #endif
  1025.  
  1026. #if defined(PNG_READ_FILLER_SUPPORTED)
  1027.    if (png_ptr->transformations & PNG_FILLER)
  1028.       png_do_read_filler(&(png_ptr->row_info), png_ptr->row_buf + 1,
  1029.          (png_uint_32)png_ptr->filler, png_ptr->flags);
  1030. #endif
  1031.  
  1032. #if defined(PNG_READ_SWAP_ALPHA_SUPPORTED)
  1033.    if (png_ptr->transformations & PNG_SWAP_ALPHA)
  1034.       png_do_read_swap_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1);
  1035. #endif
  1036.  
  1037. #if defined(PNG_READ_SWAP_SUPPORTED)
  1038.    if (png_ptr->transformations & PNG_SWAP_BYTES)
  1039.       png_do_swap(&(png_ptr->row_info), png_ptr->row_buf + 1);
  1040. #endif
  1041. }
  1042.  
  1043. #if defined(PNG_READ_PACK_SUPPORTED)
  1044. /* unpack pixels of 1, 2, or 4 bits per pixel into 1 byte per pixel,
  1045.    without changing the actual values.  Thus, if you had a row with
  1046.    a bit depth of 1, you would end up with bytes that only contained
  1047.    the numbers 0 or 1.  If you would rather they contain 0 and 255, use
  1048.    png_do_shift() after this. */
  1049. void
  1050. png_do_unpack(png_row_infop row_info, png_bytep row)
  1051. {
  1052.    png_debug(1, "in png_do_unpack\n");
  1053. #if defined(PNG_USELESS_TESTS_SUPPORTED)
  1054.    if (row != NULL && row_info != NULL && row_info->bit_depth < 8)
  1055. #else
  1056.    if (row_info->bit_depth < 8)
  1057. #endif
  1058.    {
  1059.       png_uint_32 shift, i;
  1060.       png_bytep sp, dp;
  1061.  
  1062.       switch (row_info->bit_depth)
  1063.       {
  1064.          case 1:
  1065.          {
  1066.             sp = row + (png_size_t)((row_info->width - 1) >> 3);
  1067.             dp = row + (png_size_t)row_info->width - 1;
  1068.             shift = 7 - (int)((row_info->width + 7) & 7);
  1069.             for (i = 0; i < row_info->width; i++)
  1070.             {
  1071.                *dp = (png_byte)((*sp >> shift) & 0x1);
  1072.                if (shift == 7)
  1073.                {
  1074.                   shift = 0;
  1075.                   sp--;
  1076.                }
  1077.                else
  1078.                   shift++;
  1079.  
  1080.                dp--;
  1081.             }
  1082.             break;
  1083.          }
  1084.          case 2:
  1085.          {
  1086.  
  1087.             sp = row + (png_size_t)((row_info->width - 1) >> 2);
  1088.             dp = row + (png_size_t)row_info->width - 1;
  1089.             shift = (int)((3 - ((row_info->width + 3) & 3)) << 1);
  1090.             for (i = 0; i < row_info->width; i++)
  1091.             {
  1092.                *dp = (png_byte)((*sp >> shift) & 0x3);
  1093.                if (shift == 6)
  1094.                {
  1095.                   shift = 0;
  1096.                   sp--;
  1097.                }
  1098.                else
  1099.                   shift += 2;
  1100.  
  1101.                dp--;
  1102.             }
  1103.             break;
  1104.          }
  1105.          case 4:
  1106.          {
  1107.             sp = row + (png_size_t)((row_info->width - 1) >> 1);
  1108.             dp = row + (png_size_t)row_info->width - 1;
  1109.             shift = (int)((1 - ((row_info->width + 1) & 1)) << 2);
  1110.             for (i = 0; i < row_info->width; i++)
  1111.             {
  1112.                *dp = (png_byte)((*sp >> shift) & 0xf);
  1113.                if (shift == 4)
  1114.                {
  1115.                   shift = 0;
  1116.                   sp--;
  1117.                }
  1118.                else
  1119.                   shift = 4;
  1120.  
  1121.                dp--;
  1122.             }
  1123.             break;
  1124.          }
  1125.       }
  1126.       row_info->bit_depth = 8;
  1127.       row_info->pixel_depth = (png_byte)(8 * row_info->channels);
  1128.       row_info->rowbytes = (png_size_t)row_info->width * row_info->channels;
  1129.    }
  1130. }
  1131. #endif
  1132.  
  1133. #if defined(PNG_READ_SHIFT_SUPPORTED)
  1134. /* reverse the effects of png_do_shift.  This routine merely shifts the
  1135.    pixels back to their significant bits values.  Thus, if you have
  1136.    a row of bit depth 8, but only 5 are significant, this will shift
  1137.    the values back to 0 through 31 */
  1138. void
  1139. png_do_unshift(png_row_infop row_info, png_bytep row, png_color_8p sig_bits)
  1140. {
  1141.    png_debug(1, "in png_do_unshift\n");
  1142.    if (
  1143. #if defined(PNG_USELESS_TESTS_SUPPORTED)
  1144.        row != NULL && row_info != NULL && sig_bits != NULL &&
  1145. #endif
  1146.        row_info->color_type != PNG_COLOR_TYPE_PALETTE)
  1147.    {
  1148.       int shift[4];
  1149.       int channels, c;
  1150.       png_uint_16 value;
  1151.  
  1152.       channels = 0;
  1153.       if (row_info->color_type & PNG_COLOR_MASK_COLOR)
  1154.       {
  1155.          shift[channels++] = row_info->bit_depth - sig_bits->red;
  1156.          shift[channels++] = row_info->bit_depth - sig_bits->green;
  1157.          shift[channels++] = row_info->bit_depth - sig_bits->blue;
  1158.       }
  1159.       else
  1160.       {
  1161.          shift[channels++] = row_info->bit_depth - sig_bits->gray;
  1162.       }
  1163.       if (row_info->color_type & PNG_COLOR_MASK_ALPHA)
  1164.       {
  1165.          shift[channels++] = row_info->bit_depth - sig_bits->alpha;
  1166.       }
  1167.  
  1168.       value = 0;
  1169.  
  1170.       for (c = 0; c < channels; c++)
  1171.       {
  1172.          if (shift[c] <= 0)
  1173.             shift[c] = 0;
  1174.          else
  1175.             value = 1;
  1176.       }
  1177.  
  1178.       if (!value)
  1179.          return;
  1180.  
  1181.       switch (row_info->bit_depth)
  1182.       {
  1183.          case 2:
  1184.          {
  1185.             png_bytep bp;
  1186.             png_size_t i;
  1187.  
  1188.             for (bp = row, i = 0; i < row_info->rowbytes; i++, bp++)
  1189.             {
  1190.                *bp >>= 1;
  1191.                *bp &= 0x55;
  1192.             }
  1193.             break;
  1194.          }
  1195.          case 4:
  1196.          {
  1197.             png_bytep bp;
  1198.             png_byte mask;
  1199.             png_size_t i;
  1200.  
  1201.             mask = (png_byte)(((int)0xf0 >> shift[0]) & (int)0xf0) |
  1202.                (png_byte)((int)0xf >> shift[0]);
  1203.             for (bp = row, i = 0; i < row_info->rowbytes; i++, bp++)
  1204.             {
  1205.                *bp >>= shift[0];
  1206.                *bp &= mask;
  1207.             }
  1208.             break;
  1209.          }
  1210.          case 8:
  1211.          {
  1212.             png_bytep bp;
  1213.             png_size_t i;
  1214.  
  1215.             for (bp = row, i = 0; i < row_info->width; i++)
  1216.             {
  1217.                for (c = 0; c < row_info->channels; c++, bp++)
  1218.                {
  1219.                   *bp >>= shift[c];
  1220.                }
  1221.             }
  1222.             break;
  1223.          }
  1224.          case 16:
  1225.          {
  1226.             png_bytep bp;
  1227.             png_size_t i;
  1228.  
  1229.             for (bp = row, i = 0; i < row_info->width; i++)
  1230.             {
  1231.                for (c = 0; c < row_info->channels; c++, bp += 2)
  1232.                {
  1233.                   value = (png_uint_16)((*bp << 8) + *(bp + 1));
  1234.                   value >>= shift[c];
  1235.                   *bp = (png_byte)(value >> 8);
  1236.                   *(bp + 1) = (png_byte)(value & 0xff);
  1237.                }
  1238.             }
  1239.             break;
  1240.          }
  1241.       }
  1242.    }
  1243. }
  1244. #endif
  1245.  
  1246. #if defined(PNG_READ_16_TO_8_SUPPORTED)
  1247. /* chop rows of bit depth 16 down to 8 */
  1248. void
  1249. png_do_chop(png_row_infop row_info, png_bytep row)
  1250. {
  1251.    png_debug(1, "in png_do_chop\n");
  1252. #if defined(PNG_USELESS_TESTS_SUPPORTED)
  1253.    if (row != NULL && row_info != NULL && row_info->bit_depth == 16)
  1254. #else
  1255.    if (row_info->bit_depth == 16)
  1256. #endif
  1257.    {
  1258.       png_bytep sp, dp;
  1259.       png_uint_32 i;
  1260.  
  1261.       sp = row;
  1262.       dp = row;
  1263.       for (i = 0; i < row_info->width * row_info->channels; i++, sp += 2, dp++)
  1264.       {
  1265. #if defined(PNG_READ_16_TO_8_ACCURATE_SCALE_SUPPORTED)
  1266.          /* This does a more accurate scaling of the 16-bit color
  1267.           * value, rather than a simple low-byte truncation.
  1268.           *
  1269.           * What the ideal calculation should be:
  1270.          *dp = (((((png_uint_32)(*sp) << 8) |
  1271.                    (png_uint_32)(*(sp + 1))) * 255 + 127) / 65535;
  1272.  
  1273.           * Approximate calculation with shift/add instead of multiply/divide:
  1274.          *dp = ((((png_uint_32)(*sp) << 8) |
  1275.                   (png_uint_32)((int)(*(sp + 1)) - *sp)) + 128) >> 8;
  1276.  
  1277.           * What we actually do to avoid extra shifting and conversion: */
  1278.          *dp = *sp + ((((int)(*(sp + 1)) - *sp) > 128) ? 1 : 0);
  1279. #else
  1280.          *dp = *sp;
  1281. #endif
  1282.       }
  1283.       row_info->bit_depth = 8;
  1284.       row_info->pixel_depth = (png_byte)(8 * row_info->channels);
  1285.       row_info->rowbytes = (png_size_t)row_info->width * row_info->channels;
  1286.    }
  1287. }
  1288. #endif
  1289.  
  1290. #if defined(PNG_READ_SWAP_ALPHA_SUPPORTED)
  1291. void
  1292. png_do_read_swap_alpha(png_row_infop row_info, png_bytep row)
  1293. {
  1294.    png_debug(1, "in png_do_read_swap_alpha\n");
  1295. #if defined(PNG_USELESS_TESTS_SUPPORTED)
  1296.    if (row != NULL && row_info != NULL)
  1297. #endif
  1298.    {
  1299.       if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
  1300.       {
  1301.          /* This converts from RGBA to ARGB */
  1302.          if (row_info->bit_depth == 8)
  1303.          {
  1304.             png_bytep sp, dp;
  1305.             png_byte save;
  1306.             png_uint_32 i;
  1307.  
  1308.             for (i = 0, sp = dp = row + row_info->rowbytes;
  1309.                i < row_info->width; i++)
  1310.             {
  1311.                save = *(--sp);
  1312.                *(--dp) = *(--sp);
  1313.                *(--dp) = *(--sp);
  1314.                *(--dp) = *(--sp);
  1315.                *(--dp) = save;
  1316.             }
  1317.          }
  1318.          /* This converts from RRGGBBAA to AARRGGBB */
  1319.          else
  1320.          {
  1321.             png_bytep sp, dp;
  1322.             png_byte save[2];
  1323.             png_uint_32 i;
  1324.  
  1325.             for (i = 0, sp = dp = row + row_info->rowbytes;
  1326.                i < row_info->width; i++)
  1327.             {
  1328.                save[0] = *(--sp);
  1329.                save[1] = *(--sp);
  1330.                *(--dp) = *(--sp);
  1331.                *(--dp) = *(--sp);
  1332.                *(--dp) = *(--sp);
  1333.                *(--dp) = *(--sp);
  1334.                *(--dp) = *(--sp);
  1335.                *(--dp) = *(--sp);
  1336.                *(--dp) = save[0];
  1337.                *(--dp) = save[1];
  1338.             }
  1339.          }
  1340.       }
  1341.       else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
  1342.       {
  1343.          /* This converts from GA to AG */
  1344.          if (row_info->bit_depth == 8)
  1345.          {
  1346.             png_bytep sp, dp;
  1347.             png_byte save;
  1348.             png_uint_32 i;
  1349.  
  1350.             for (i = 0, sp = dp = row + row_info->rowbytes;
  1351.                i < row_info->width; i++)
  1352.             {
  1353.                save = *(--sp);
  1354.                *(--dp) = *(--sp);
  1355.                *(--dp) = save;
  1356.             }
  1357.          }
  1358.          /* This converts from GGAA to AAGG */
  1359.          else
  1360.          {
  1361.             png_bytep sp, dp;
  1362.             png_byte save[2];
  1363.             png_uint_32 i;
  1364.  
  1365.             for (i = 0, sp = dp = row + row_info->rowbytes;
  1366.                i < row_info->width; i++)
  1367.             {
  1368.                save[0] = *(--sp);
  1369.                save[1] = *(--sp);
  1370.                *(--dp) = *(--sp);
  1371.                *(--dp) = *(--sp);
  1372.                *(--dp) = save[0];
  1373.                *(--dp) = save[1];
  1374.             }
  1375.          }
  1376.       }
  1377.    }
  1378. }
  1379. #endif
  1380.  
  1381. #if defined(PNG_READ_FILLER_SUPPORTED)
  1382. /* Add filler channel if we have RGB color */
  1383. void
  1384. png_do_read_filler(png_row_infop row_info, png_bytep row,
  1385.    png_uint_32 filler, png_uint_32 flags)
  1386. {
  1387.    png_bytep sp, dp;
  1388.    png_uint_32 i;
  1389.  
  1390.    png_debug(1, "in png_do_read_filler\n");
  1391.    if (
  1392. #if defined(PNG_USELESS_TESTS_SUPPORTED)
  1393.        row != NULL  && row_info != NULL &&
  1394. #endif
  1395.        row_info->color_type == PNG_COLOR_TYPE_RGB && row_info->bit_depth == 8)
  1396.    {
  1397.       /* This changes the data from RGB to RGBX */
  1398.       if (flags & PNG_FLAG_FILLER_AFTER)
  1399.       {
  1400.          for (i = 1, sp = row + (png_size_t)row_info->width * 3,
  1401.             dp = row + (png_size_t)row_info->width * 4;
  1402.             i < row_info->width;
  1403.             i++)
  1404.          {
  1405.             *(--dp) = (png_byte)filler;
  1406.             *(--dp) = *(--sp);
  1407.             *(--dp) = *(--sp);
  1408.             *(--dp) = *(--sp);
  1409.          }
  1410.          *(--dp) = (png_byte)filler;
  1411.          row_info->channels = 4;
  1412.          row_info->pixel_depth = 32;
  1413.          row_info->rowbytes = (png_size_t)row_info->width * 4;
  1414.       }
  1415.       /* This changes the data from RGB to XRGB */
  1416.       else
  1417.       {
  1418.          for (i = 0, sp = row + (png_size_t)row_info->width * 3,
  1419.             dp = row + (png_size_t)row_info->width * 4;
  1420.             i < row_info->width;
  1421.             i++)
  1422.          {
  1423.             *(--dp) = *(--sp);
  1424.             *(--dp) = *(--sp);
  1425.             *(--dp) = *(--sp);
  1426.             *(--dp) = (png_byte)filler;
  1427.          }
  1428.          row_info->channels = 4;
  1429.          row_info->pixel_depth = 32;
  1430.          row_info->rowbytes = (png_size_t)row_info->width * 4;
  1431.       }
  1432.    }
  1433. }
  1434. #endif
  1435.  
  1436. #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
  1437. /* expand grayscale files to RGB, with or without alpha */
  1438. void
  1439. png_do_gray_to_rgb(png_row_infop row_info, png_bytep row)
  1440. {
  1441.    png_bytep sp, dp;
  1442.    png_uint_32 i;
  1443.  
  1444.    png_debug(1, "in png_do_gray_to_rgb\n");
  1445.    if (row_info->bit_depth >= 8 &&
  1446. #if defined(PNG_USELESS_TESTS_SUPPORTED)
  1447.        row != NULL && row_info != NULL &&
  1448. #endif
  1449.       !(row_info->color_type & PNG_COLOR_MASK_COLOR))
  1450.    {
  1451.       if (row_info->color_type == PNG_COLOR_TYPE_GRAY)
  1452.       {
  1453.          if (row_info->bit_depth == 8)
  1454.          {
  1455.             for (i = 0, sp = row + (png_size_t)row_info->width - 1,
  1456.                dp = row + (png_size_t)row_info->width * 3 - 1;
  1457.                i < row_info->width;
  1458.                i++)
  1459.             {
  1460.                *(dp--) = *sp;
  1461.                *(dp--) = *sp;
  1462.                *(dp--) = *sp;
  1463.                sp--;
  1464.             }
  1465.          }
  1466.          else
  1467.          {
  1468.             for (i = 0, sp = row + (png_size_t)row_info->width * 2 - 1,
  1469.                dp = row + (png_size_t)row_info->width * 6 - 1;
  1470.                i < row_info->width;
  1471.                i++)
  1472.             {
  1473.                *(dp--) = *sp;
  1474.                *(dp--) = *(sp - 1);
  1475.                *(dp--) = *sp;
  1476.                *(dp--) = *(sp - 1);
  1477.                *(dp--) = *sp;
  1478.                *(dp--) = *(sp - 1);
  1479.                sp--;
  1480.                sp--;
  1481.             }
  1482.          }
  1483.       }
  1484.       else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
  1485.       {
  1486.          if (row_info->bit_depth == 8)
  1487.          {
  1488.             for (i = 0, sp = row + (png_size_t)row_info->width * 2 - 1,
  1489.                dp = row + (png_size_t)row_info->width * 4 - 1;
  1490.                i < row_info->width;
  1491.                i++)
  1492.             {
  1493.                *(dp--) = *(sp--);
  1494.                *(dp--) = *sp;
  1495.                *(dp--) = *sp;
  1496.                *(dp--) = *sp;
  1497.                sp--;
  1498.             }
  1499.          }
  1500.          else
  1501.          {
  1502.             for (i = 0, sp = row + (png_size_t)row_info->width * 4 - 1,
  1503.                dp = row + (png_size_t)row_info->width * 8 - 1;
  1504.                i < row_info->width;
  1505.                i++)
  1506.             {
  1507.                *(dp--) = *(sp--);
  1508.                *(dp--) = *(sp--);
  1509.                *(dp--) = *sp;
  1510.                *(dp--) = *(sp - 1);
  1511.                *(dp--) = *sp;
  1512.                *(dp--) = *(sp - 1);
  1513.                *(dp--) = *sp;
  1514.                *(dp--) = *(sp - 1);
  1515.                sp--;
  1516.                sp--;
  1517.             }
  1518.          }
  1519.       }
  1520.       row_info->channels += (png_byte)2;
  1521.       row_info->color_type |= PNG_COLOR_MASK_COLOR;
  1522.       row_info->pixel_depth = (png_byte)(row_info->channels *
  1523.          row_info->bit_depth);
  1524.       row_info->rowbytes = (png_size_t)((row_info->width *
  1525.          row_info->pixel_depth + 7) >> 3);
  1526.    }
  1527. }
  1528. #endif
  1529.  
  1530. /* build a grayscale palette.  Palette is assumed to be 1 << bit_depth
  1531.    large of png_color.  This lets grayscale images be treated as
  1532.    paletted.  Most useful for gamma correction and simplification
  1533.    of code. */
  1534. void
  1535. png_build_grayscale_palette(int bit_depth, png_colorp palette)
  1536. {
  1537.    int num_palette;
  1538.    int color_inc;
  1539.    int i;
  1540.    int v;
  1541.  
  1542.    png_debug(1, "in png_do_build_grayscale_palette\n");
  1543.    if (palette == NULL)
  1544.       return;
  1545.  
  1546.    switch (bit_depth)
  1547.    {
  1548.       case 1:
  1549.          num_palette = 2;
  1550.          color_inc = 0xff;
  1551.          break;
  1552.       case 2:
  1553.          num_palette = 4;
  1554.          color_inc = 0x55;
  1555.          break;
  1556.       case 4:
  1557.          num_palette = 16;
  1558.          color_inc = 0x11;
  1559.          break;
  1560.       case 8:
  1561.          num_palette = 256;
  1562.          color_inc = 1;
  1563.          break;
  1564.       default:
  1565.          num_palette = 0;
  1566.          color_inc = 0;
  1567.          break;
  1568.    }
  1569.  
  1570.    for (i = 0, v = 0; i < num_palette; i++, v += color_inc)
  1571.    {
  1572.       palette[i].red = (png_byte)v;
  1573.       palette[i].green = (png_byte)v;
  1574.       palette[i].blue = (png_byte)v;
  1575.    }
  1576. }
  1577.  
  1578. /* This function is currently unused.  Do we really need it? */
  1579. #if defined(PNG_READ_DITHER_SUPPORTED) && defined(PNG_CORRECT_PALETTE_SUPPORTED)
  1580. void
  1581. png_correct_palette(png_structp png_ptr, png_colorp palette,
  1582.    int num_palette)
  1583. {
  1584.    png_debug(1, "in png_correct_palette\n");
  1585. #if defined(PNG_READ_BACKGROUND_SUPPORTED) && defined(PNG_READ_GAMMA_SUPPORTED)
  1586.    if ((png_ptr->transformations & (PNG_GAMMA)) &&
  1587.       (png_ptr->transformations & (PNG_BACKGROUND)))
  1588.    {
  1589.       png_color back, back_1;
  1590.  
  1591.       if (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_FILE)
  1592.       {
  1593.          back.red = png_ptr->gamma_table[png_ptr->background.red];
  1594.          back.green = png_ptr->gamma_table[png_ptr->background.green];
  1595.          back.blue = png_ptr->gamma_table[png_ptr->background.blue];
  1596.  
  1597.          back_1.red = png_ptr->gamma_to_1[png_ptr->background.red];
  1598.          back_1.green = png_ptr->gamma_to_1[png_ptr->background.green];
  1599.          back_1.blue = png_ptr->gamma_to_1[png_ptr->background.blue];
  1600.       }
  1601.       else
  1602.       {
  1603.          double g;
  1604.  
  1605.          g = 1.0 / (png_ptr->background_gamma * png_ptr->display_gamma);
  1606.  
  1607.          if (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_SCREEN ||
  1608.              fabs(g - 1.0) < PNG_GAMMA_THRESHOLD)
  1609.          {
  1610.             back.red = png_ptr->background.red;
  1611.             back.green = png_ptr->background.green;
  1612.             back.blue = png_ptr->background.blue;
  1613.          }
  1614.          else
  1615.          {
  1616.             back.red =
  1617.                (png_byte)(pow((double)png_ptr->background.red/255, g) *
  1618.                 255.0 + 0.5);
  1619.             back.green =
  1620.                (png_byte)(pow((double)png_ptr->background.green/255, g) *
  1621.                 255.0 + 0.5);
  1622.             back.blue =
  1623.                (png_byte)(pow((double)png_ptr->background.blue/255, g) *
  1624.                 255.0 + 0.5);
  1625.          }
  1626.  
  1627.          g = 1.0 / png_ptr->background_gamma;
  1628.  
  1629.          back_1.red =
  1630.             (png_byte)(pow((double)png_ptr->background.red/255, g) *
  1631.              255.0 + 0.5);
  1632.          back_1.green =
  1633.             (png_byte)(pow((double)png_ptr->background.green/255, g) *
  1634.              255.0 + 0.5);
  1635.          back_1.blue =
  1636.             (png_byte)(pow((double)png_ptr->background.blue/255, g) *
  1637.              255.0 + 0.5);
  1638.       }
  1639.  
  1640.       if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
  1641.       {
  1642.          png_uint_32 i;
  1643.  
  1644.          for (i = 0; i < (png_uint_32)num_palette; i++)
  1645.          {
  1646.             if (i < png_ptr->num_trans && png_ptr->trans[i] == 0)
  1647.             {
  1648.                palette[i] = back;
  1649.             }
  1650.             else if (i < png_ptr->num_trans && png_ptr->trans[i] != 0xff)
  1651.             {
  1652.                png_byte v, w;
  1653.  
  1654.                v = png_ptr->gamma_to_1[png_ptr->palette[i].red];
  1655.                png_composite(w, v, png_ptr->trans[i], back_1.red);
  1656.                palette[i].red = png_ptr->gamma_from_1[w];
  1657.  
  1658.                v = png_ptr->gamma_to_1[png_ptr->palette[i].green];
  1659.                png_composite(w, v, png_ptr->trans[i], back_1.green);
  1660.                palette[i].green = png_ptr->gamma_from_1[w];
  1661.  
  1662.                v = png_ptr->gamma_to_1[png_ptr->palette[i].blue];
  1663.                png_composite(w, v, png_ptr->trans[i], back_1.blue);
  1664.                palette[i].blue = png_ptr->gamma_from_1[w];
  1665.             }
  1666.             else
  1667.             {
  1668.                palette[i].red = png_ptr->gamma_table[palette[i].red];
  1669.                palette[i].green = png_ptr->gamma_table[palette[i].green];
  1670.                palette[i].blue = png_ptr->gamma_table[palette[i].blue];
  1671.             }
  1672.          }
  1673.       }
  1674.       else
  1675.       {
  1676.          int i;
  1677.  
  1678.          for (i = 0; i < num_palette; i++)
  1679.          {
  1680.             if (palette[i].red == (png_byte)png_ptr->trans_values.gray)
  1681.             {
  1682.                palette[i] = back;
  1683.             }
  1684.             else
  1685.             {
  1686.                palette[i].red = png_ptr->gamma_table[palette[i].red];
  1687.                palette[i].green = png_ptr->gamma_table[palette[i].green];
  1688.                palette[i].blue = png_ptr->gamma_table[palette[i].blue];
  1689.             }
  1690.          }
  1691.       }
  1692.    }
  1693.    else
  1694. #endif
  1695. #if defined(PNG_READ_GAMMA_SUPPORTED)
  1696.    if (png_ptr->transformations & PNG_GAMMA)
  1697.    {
  1698.       int i;
  1699.  
  1700.       for (i = 0; i < num_palette; i++)
  1701.       {
  1702.          palette[i].red = png_ptr->gamma_table[palette[i].red];
  1703.          palette[i].green = png_ptr->gamma_table[palette[i].green];
  1704.          palette[i].blue = png_ptr->gamma_table[palette[i].blue];
  1705.       }
  1706.    }
  1707. #if defined(PNG_READ_BACKGROUND_SUPPORTED)
  1708.    else
  1709. #endif
  1710. #endif
  1711. #if defined(PNG_READ_BACKGROUND_SUPPORTED)
  1712.    if (png_ptr->transformations & PNG_BACKGROUND)
  1713.    {
  1714.       if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
  1715.       {
  1716.          int i;
  1717.          png_color back;
  1718.  
  1719.          back.red   = (png_byte)png_ptr->background.red;
  1720.          back.green = (png_byte)png_ptr->background.green;
  1721.          back.blue  = (png_byte)png_ptr->background.blue;
  1722.  
  1723.          for (i = 0; i < num_palette; i++)
  1724.          {
  1725.             if (i >= (int)png_ptr->num_trans ||
  1726.                png_ptr->trans[i] == 0)
  1727.             {
  1728.                palette[i].red = back.red;
  1729.                palette[i].green = back.green;
  1730.                palette[i].blue = back.blue;
  1731.             }
  1732.             else if (i < (int)png_ptr->num_trans ||
  1733.                png_ptr->trans[i] != 0xff)
  1734.             {
  1735.                png_composite(palette[i].red, png_ptr->palette[i].red,
  1736.                   png_ptr->trans[i], back.red);
  1737.                png_composite(palette[i].green, png_ptr->palette[i].green,
  1738.                   png_ptr->trans[i], back.green);
  1739.                png_composite(palette[i].blue, png_ptr->palette[i].blue,
  1740.                   png_ptr->trans[i], back.blue);
  1741.             }
  1742.          }
  1743.       }
  1744.       else /* assume grayscale palette (what else could it be?) */
  1745.       {
  1746.          int i;
  1747.  
  1748.          for (i = 0; i < num_palette; i++)
  1749.          {
  1750.             if (i == (png_byte)png_ptr->trans_values.gray)
  1751.             {
  1752.                palette[i].red = (png_byte)png_ptr->background.red;
  1753.                palette[i].green = (png_byte)png_ptr->background.green;
  1754.                palette[i].blue = (png_byte)png_ptr->background.blue;
  1755.             }
  1756.          }
  1757.       }
  1758.    }
  1759. #endif
  1760. }
  1761. #endif
  1762.  
  1763. #if defined(PNG_READ_BACKGROUND_SUPPORTED)
  1764. /* Replace any alpha or transparency with the supplied background color.
  1765.    "background" is already in the screen gamma, while "background_1" is
  1766.    at a gamma of 1.0.  Paletted files have already been taken care of. */
  1767. void
  1768. png_do_background(png_row_infop row_info, png_bytep row,
  1769.    png_color_16p trans_values, png_color_16p background,
  1770.    png_color_16p background_1,
  1771.    png_bytep gamma_table, png_bytep gamma_from_1, png_bytep gamma_to_1,
  1772.    png_uint_16pp gamma_16, png_uint_16pp gamma_16_from_1,
  1773.    png_uint_16pp gamma_16_to_1, int gamma_shift)
  1774. {
  1775.    png_bytep sp, dp;
  1776.    png_uint_32 i;
  1777.    int shift;
  1778.  
  1779.    png_debug(1, "in png_do_background\n");
  1780.    if (background != NULL &&
  1781. #if defined(PNG_USELESS_TESTS_SUPPORTED)
  1782.        row != NULL && row_info != NULL &&
  1783. #endif
  1784.       (!(row_info->color_type & PNG_COLOR_MASK_ALPHA) ||
  1785.       (row_info->color_type != PNG_COLOR_TYPE_PALETTE && trans_values)))
  1786.    {
  1787.       switch (row_info->color_type)
  1788.       {
  1789.          case PNG_COLOR_TYPE_GRAY:
  1790.          {
  1791.             /* We currently don't do gamma correction for 2 and 4 bit */
  1792.             switch (row_info->bit_depth)
  1793.             {
  1794.                case 1:
  1795.                {
  1796.                   sp = row;
  1797.                   shift = 7;
  1798.                   for (i = 0; i < row_info->width; i++)
  1799.                   {
  1800.                      if (((*sp >> shift) & 0x1) == trans_values->gray)
  1801.                      {
  1802.                         *sp &= (png_byte)((0x7f7f >> (7 - shift)) & 0xff);
  1803.                         *sp |= (png_byte)(background->gray << shift);
  1804.                      }
  1805.                      if (!shift)
  1806.                      {
  1807.                         shift = 7;
  1808.                         sp++;
  1809.                      }
  1810.                      else
  1811.                         shift--;
  1812.                   }
  1813.                   break;
  1814.                }
  1815.                case 2:
  1816.                {
  1817.                   sp = row;
  1818.                   shift = 6;
  1819.                   for (i = 0; i < row_info->width; i++)
  1820.                   {
  1821.                      if (((*sp >> shift) & 0x3) == trans_values->gray)
  1822.                      {
  1823.                         *sp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff);
  1824.                         *sp |= (png_byte)(background->gray << shift);
  1825.                      }
  1826.                      if (!shift)
  1827.                      {
  1828.                         shift = 6;
  1829.                         sp++;
  1830.                      }
  1831.                      else
  1832.                         shift -= 2;
  1833.                   }
  1834.                   break;
  1835.                }
  1836.                case 4:
  1837.                {
  1838.                   sp = row;
  1839.                   shift = 4;
  1840.                   for (i = 0; i < row_info->width; i++)
  1841.                   {
  1842.                      if (((*sp >> shift) & 0xf) == trans_values->gray)
  1843.                      {
  1844.                         *sp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff);
  1845.                         *sp |= (png_byte)(background->gray << shift);
  1846.                      }
  1847.                      if (!shift)
  1848.                      {
  1849.                         shift = 4;
  1850.                         sp++;
  1851.                      }
  1852.                      else
  1853.                         shift -= 4;
  1854.                   }
  1855.                   break;
  1856.                }
  1857.                case 8:
  1858.                {
  1859. #if defined(PNG_READ_GAMMA_SUPPORTED)
  1860.                   if (gamma_table != NULL)
  1861.                   {
  1862.                      for (i = 0, sp = row; i < row_info->width; i++, sp++)
  1863.                      {
  1864.                         if (*sp == trans_values->gray)
  1865.                         {
  1866.                            *sp = (png_byte)background->gray;
  1867.                         }
  1868.                         else
  1869.                         {
  1870.                            *sp = gamma_table[*sp];
  1871.                         }
  1872.                      }
  1873.                   }
  1874.                   else
  1875. #endif
  1876.                   {
  1877.                      for (i = 0, sp = row; i < row_info->width; i++, sp++)
  1878.                      {
  1879.                         if (*sp == trans_values->gray)
  1880.                         {
  1881.                            *sp = (png_byte)background->gray;
  1882.                         }
  1883.                      }
  1884.                   }
  1885.                   break;
  1886.                }
  1887.                case 16:
  1888.                {
  1889. #if defined(PNG_READ_GAMMA_SUPPORTED)
  1890.                   if (gamma_16 != NULL)
  1891.                   {
  1892.                      for (i = 0, sp = row; i < row_info->width; i++, sp += 2)
  1893.                      {
  1894.                         png_uint_16 v;
  1895.  
  1896.                         v = ((png_uint_16)(*sp) << 8) + *(sp + 1);
  1897.                         if (v == trans_values->gray)
  1898.                         {
  1899.                            /* background is already in screen gamma */
  1900.                            *sp = (png_byte)((background->gray >> 8) & 0xff);
  1901.                            *(sp + 1) = (png_byte)(background->gray & 0xff);
  1902.                         }
  1903.                         else
  1904.                         {
  1905.                            v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
  1906.                            *sp = (png_byte)((v >> 8) & 0xff);
  1907.                            *(sp + 1) = (png_byte)(v & 0xff);
  1908.                         }
  1909.                      }
  1910.                   }
  1911.                   else
  1912. #endif
  1913.                   {
  1914.                      for (i = 0, sp = row; i < row_info->width; i++, sp += 2)
  1915.                      {
  1916.                         png_uint_16 v;
  1917.  
  1918.                         v = ((png_uint_16)(*sp) << 8) + *(sp + 1);
  1919.                         if (v == trans_values->gray)
  1920.                         {
  1921.                            *sp = (png_byte)((background->gray >> 8) & 0xff);
  1922.                            *(sp + 1) = (png_byte)(background->gray & 0xff);
  1923.                         }
  1924.                      }
  1925.                   }
  1926.                   break;
  1927.                }
  1928.             }
  1929.             break;
  1930.          }
  1931.          case PNG_COLOR_TYPE_RGB:
  1932.          {
  1933.             if (row_info->bit_depth == 8)
  1934.             {
  1935. #if defined(PNG_READ_GAMMA_SUPPORTED)
  1936.                if (gamma_table != NULL)
  1937.                {
  1938.                   for (i = 0, sp = row; i < row_info->width; i++, sp += 3)
  1939.                   {
  1940.                      if (*sp == trans_values->red &&
  1941.                         *(sp + 1) == trans_values->green &&
  1942.                         *(sp + 2) == trans_values->blue)
  1943.                      {
  1944.                         *sp = (png_byte)background->red;
  1945.                         *(sp + 1) = (png_byte)background->green;
  1946.                         *(sp + 2) = (png_byte)background->blue;
  1947.                      }
  1948.                      else
  1949.                      {
  1950.                         *sp = gamma_table[*sp];
  1951.                         *(sp + 1) = gamma_table[*(sp + 1)];
  1952.                         *(sp + 2) = gamma_table[*(sp + 2)];
  1953.                      }
  1954.                   }
  1955.                }
  1956.                else
  1957. #endif
  1958.                {
  1959.                   for (i = 0, sp = row; i < row_info->width; i++, sp += 3)
  1960.                   {
  1961.                      if (*sp == trans_values->red &&
  1962.                         *(sp + 1) == trans_values->green &&
  1963.                         *(sp + 2) == trans_values->blue)
  1964.                      {
  1965.                         *sp = (png_byte)background->red;
  1966.                         *(sp + 1) = (png_byte)background->green;
  1967.                         *(sp + 2) = (png_byte)background->blue;
  1968.                      }
  1969.                   }
  1970.                }
  1971.             }
  1972.             else /* if (row_info->bit_depth == 16) */
  1973.             {
  1974. #if defined(PNG_READ_GAMMA_SUPPORTED)
  1975.                if (gamma_16 != NULL)
  1976.                {
  1977.                   for (i = 0, sp = row; i < row_info->width; i++, sp += 6)
  1978.                   {
  1979.                      png_uint_16 r, g, b;
  1980.  
  1981.                      r = ((png_uint_16)(*sp) << 8) + *(sp + 1);
  1982.                      g = ((png_uint_16)(*(sp + 2)) << 8) + *(sp + 3);
  1983.                      b = ((png_uint_16)(*(sp + 4)) << 8) + *(sp + 5);
  1984.                      if (r == trans_values->red && g == trans_values->green &&
  1985.                         b == trans_values->blue)
  1986.                      {
  1987.                         /* background is already in screen gamma */
  1988.                         *sp = (png_byte)((background->red >> 8) & 0xff);
  1989.                         *(sp + 1) = (png_byte)(background->red & 0xff);
  1990.                         *(sp + 2) = (png_byte)((background->green >> 8) & 0xff);
  1991.                         *(sp + 3) = (png_byte)(background->green & 0xff);
  1992.                         *(sp + 4) = (png_byte)((background->blue >> 8) & 0xff);
  1993.                         *(sp + 5) = (png_byte)(background->blue & 0xff);
  1994.                      }
  1995.                      else
  1996.                      {
  1997.                         png_uint_16 v;
  1998.                         v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
  1999.                         *sp = (png_byte)((v >> 8) & 0xff);
  2000.                         *(sp + 1) = (png_byte)(v & 0xff);
  2001.                         v = gamma_16[*(sp + 3) >> gamma_shift][*(sp + 2)];
  2002.                         *(sp + 2) = (png_byte)((v >> 8) & 0xff);
  2003.                         *(sp + 3) = (png_byte)(v & 0xff);
  2004.                         v = gamma_16[*(sp + 5) >> gamma_shift][*(sp + 4)];
  2005.                         *(sp + 4) = (png_byte)((v >> 8) & 0xff);
  2006.                         *(sp + 5) = (png_byte)(v & 0xff);
  2007.                      }
  2008.                   }
  2009.                }
  2010.                else
  2011. #endif
  2012.                {
  2013.                   for (i = 0, sp = row; i < row_info->width; i++, sp += 6)
  2014.                   {
  2015.                      png_uint_16 r, g, b;
  2016.  
  2017.                      r = ((png_uint_16)(*sp) << 8) + *(sp + 1);
  2018.                      g = ((png_uint_16)(*(sp + 2)) << 8) + *(sp + 3);
  2019.                      b = ((png_uint_16)(*(sp + 4)) << 8) + *(sp + 5);
  2020.                      if (r == trans_values->red && g == trans_values->green &&
  2021.                         b == trans_values->blue)
  2022.                      {
  2023.                         *sp = (png_byte)((background->red >> 8) & 0xff);
  2024.                         *(sp + 1) = (png_byte)(background->red & 0xff);
  2025.                         *(sp + 2) = (png_byte)((background->green >> 8) & 0xff);
  2026.                         *(sp + 3) = (png_byte)(background->green & 0xff);
  2027.                         *(sp + 4) = (png_byte)((background->blue >> 8) & 0xff);
  2028.                         *(sp + 5) = (png_byte)(background->blue & 0xff);
  2029.                      }
  2030.                   }
  2031.                }
  2032.             }
  2033.             break;
  2034.          }
  2035.          case PNG_COLOR_TYPE_GRAY_ALPHA:
  2036.          {
  2037.             if (row_info->bit_depth == 8)
  2038.             {
  2039. #if defined(PNG_READ_GAMMA_SUPPORTED)
  2040.                if (gamma_to_1 != NULL && gamma_from_1 != NULL &&
  2041.                    gamma_table != NULL)
  2042.                {
  2043.                   for (i = 0, sp = row, dp = row;
  2044.                      i < row_info->width; i++, sp += 2, dp++)
  2045.                   {
  2046.                      png_uint_16 a;
  2047.  
  2048.                      a = *(sp + 1);
  2049.                      if (a == 0xff)
  2050.                      {
  2051.                         *dp = gamma_table[*sp];
  2052.                      }
  2053.                      else if (a == 0)
  2054.                      {
  2055.                         /* background is already in screen gamma */
  2056.                         *dp = (png_byte)background->gray;
  2057.                      }
  2058.                      else
  2059.                      {
  2060.                         png_byte v, w;
  2061.  
  2062.                         v = gamma_to_1[*sp];
  2063.                         png_composite(w, v, a, background_1->gray);
  2064.                         *dp = gamma_from_1[w];
  2065.                      }
  2066.                   }
  2067.                }
  2068.                else
  2069. #endif
  2070.                {
  2071.                   for (i = 0, sp = row, dp = row;
  2072.                      i < row_info->width; i++, sp += 2, dp++)
  2073.                   {
  2074.                      png_byte a;
  2075.  
  2076.                      a = *(sp + 1);
  2077.                      if (a == 0xff)
  2078.                      {
  2079.                         *dp = *sp;
  2080.                      }
  2081.                      else if (a == 0)
  2082.                      {
  2083.                         *dp = (png_byte)background->gray;
  2084.                      }
  2085.                      else
  2086.                      {
  2087.                         png_composite(*dp, *sp, a, background_1->gray);
  2088.                      }
  2089.                   }
  2090.                }
  2091.             }
  2092.             else /* if (png_ptr->bit_depth == 16) */
  2093.             {
  2094. #if defined(PNG_READ_GAMMA_SUPPORTED)
  2095.                if (gamma_16 != NULL && gamma_16_from_1 != NULL &&
  2096.                    gamma_16_to_1 != NULL)
  2097.                {
  2098.                   for (i = 0, sp = row, dp = row;
  2099.                      i < row_info->width; i++, sp += 4, dp += 2)
  2100.                   {
  2101.                      png_uint_16 a;
  2102.  
  2103.                      a = ((png_uint_16)(*(sp + 2)) << 8) + *(sp + 3);
  2104.                      if (a == (png_uint_16)0xffff)
  2105.                      {
  2106.                         png_uint_16 v;
  2107.  
  2108.                         v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
  2109.                         *dp = (png_byte)((v >> 8) & 0xff);
  2110.                         *(dp + 1) = (png_byte)(v & 0xff);
  2111.                      }
  2112.                      else if (a == 0)
  2113.                      {
  2114.                         /* background is already in screen gamma */
  2115.                         *dp = (png_byte)((background->gray >> 8) & 0xff);
  2116.                         *(dp + 1) = (png_byte)(background->gray & 0xff);
  2117.                      }
  2118.                      else
  2119.                      {
  2120.                         png_uint_16 g, v, w;
  2121.  
  2122.                         g = gamma_16_to_1[*(sp + 1) >> gamma_shift][*sp];
  2123.                         png_composite_16(v, g, a, background_1->gray);
  2124.                         w = gamma_16_from_1[(v&0xff) >> gamma_shift][v >> 8];
  2125.                         *dp = (png_byte)((w >> 8) & 0xff);
  2126.                         *(dp + 1) = (png_byte)(w & 0xff);
  2127.                      }
  2128.                   }
  2129.                }
  2130.                else
  2131. #endif
  2132.                {
  2133.                   for (i = 0, sp = row, dp = row;
  2134.                      i < row_info->width; i++, sp += 4, dp += 2)
  2135.                   {
  2136.                      png_uint_16 a;
  2137.  
  2138.                      a = ((png_uint_16)(*(sp + 2)) << 8) + *(sp + 3);
  2139.                      if (a == (png_uint_16)0xffff)
  2140.                      {
  2141.                         png_memcpy(dp, sp, 2);
  2142.                      }
  2143.                      else if (a == 0)
  2144.                      {
  2145.                         *dp = (png_byte)((background->gray >> 8) & 0xff);
  2146.                         *(dp + 1) = (png_byte)(background->gray & 0xff);
  2147.                      }
  2148.                      else
  2149.                      {
  2150.                         png_uint_16 g, v;
  2151.  
  2152.                         g = ((png_uint_16)(*sp) << 8) + *(sp + 1);
  2153.                         png_composite_16(v, g, a, background_1->gray);
  2154.                         *dp = (png_byte)((v >> 8) & 0xff);
  2155.                         *(dp + 1) = (png_byte)(v & 0xff);
  2156.                      }
  2157.                   }
  2158.                }
  2159.             }
  2160.             break;
  2161.          }
  2162.          case PNG_COLOR_TYPE_RGB_ALPHA:
  2163.          {
  2164.             if (row_info->bit_depth == 8)
  2165.             {
  2166. #if defined(PNG_READ_GAMMA_SUPPORTED)
  2167.                if (gamma_to_1 != NULL && gamma_from_1 != NULL &&
  2168.                    gamma_table != NULL)
  2169.                {
  2170.                   for (i = 0, sp = row, dp = row;
  2171.                      i < row_info->width; i++, sp += 4, dp += 3)
  2172.                   {
  2173.                      png_byte a;
  2174.  
  2175.                      a = *(sp + 3);
  2176.                      if (a == 0xff)
  2177.                      {
  2178.                         *dp = gamma_table[*sp];
  2179.                         *(dp + 1) = gamma_table[*(sp + 1)];
  2180.                         *(dp + 2) = gamma_table[*(sp + 2)];
  2181.                      }
  2182.                      else if (a == 0)
  2183.                      {
  2184.                         /* background is already in screen gamma */
  2185.                         *dp = (png_byte)background->red;
  2186.                         *(dp + 1) = (png_byte)background->green;
  2187.                         *(dp + 2) = (png_byte)background->blue;
  2188.                      }
  2189.                      else
  2190.                      {
  2191.                         png_byte v, w;
  2192.  
  2193.                         v = gamma_to_1[*sp];
  2194.                         png_composite(w, v, a, background_1->red);
  2195.                         *dp = gamma_from_1[w];
  2196.                         v = gamma_to_1[*(sp + 1)];
  2197.                         png_composite(w, v, a, background_1->green);
  2198.                         *(dp + 1) = gamma_from_1[w];
  2199.                         v = gamma_to_1[*(sp + 2)];
  2200.                         png_composite(w, v, a, background_1->blue);
  2201.                         *(dp + 2) = gamma_from_1[w];
  2202.                      }
  2203.                   }
  2204.                }
  2205.                else
  2206. #endif
  2207.                {
  2208.                   for (i = 0, sp = row, dp = row;
  2209.                      i < row_info->width; i++, sp += 4, dp += 3)
  2210.                   {
  2211.                      png_byte a;
  2212.  
  2213.                      a = *(sp + 3);
  2214.                      if (a == 0xff)
  2215.                      {
  2216.                         *dp = *sp;
  2217.                         *(dp + 1) = *(sp + 1);
  2218.                         *(dp + 2) = *(sp + 2);
  2219.                      }
  2220.                      else if (a == 0)
  2221.                      {
  2222.                         *dp = (png_byte)background->red;
  2223.                         *(dp + 1) = (png_byte)background->green;
  2224.                         *(dp + 2) = (png_byte)background->blue;
  2225.                      }
  2226.                      else
  2227.                      {
  2228.                         png_composite(*dp, *sp, a, background->red);
  2229.                         png_composite(*(dp + 1), *(sp + 1), a,
  2230.                            background->green);
  2231.                         png_composite(*(dp + 2), *(sp + 2), a,
  2232.                            background->blue);
  2233.                      }
  2234.                   }
  2235.                }
  2236.             }
  2237.             else /* if (row_info->bit_depth == 16) */
  2238.             {
  2239. #if defined(PNG_READ_GAMMA_SUPPORTED)
  2240.                if (gamma_16 != NULL && gamma_16_from_1 != NULL &&
  2241.                    gamma_16_to_1 != NULL)
  2242.                {
  2243.                   for (i = 0, sp = row, dp = row;
  2244.                      i < row_info->width; i++, sp += 8, dp += 6)
  2245.                   {
  2246.                      png_uint_16 a;
  2247.  
  2248.                      a = (png_uint_16)(((png_uint_16)(*(sp + 6)) << 8) +
  2249.                          (png_uint_16)(*(sp + 7)));
  2250.                      if (a == (png_uint_16)0xffff)
  2251.                      {
  2252.                         png_uint_16 v;
  2253.  
  2254.                         v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
  2255.                         *dp = (png_byte)((v >> 8) & 0xff);
  2256.                         *(dp + 1) = (png_byte)(v & 0xff);
  2257.                         v = gamma_16[*(sp + 3) >> gamma_shift][*(sp + 2)];
  2258.                         *(dp + 2) = (png_byte)((v >> 8) & 0xff);
  2259.                         *(dp + 3) = (png_byte)(v & 0xff);
  2260.                         v = gamma_16[*(sp + 5) >> gamma_shift][*(sp + 4)];
  2261.                         *(dp + 4) = (png_byte)((v >> 8) & 0xff);
  2262.                         *(dp + 5) = (png_byte)(v & 0xff);
  2263.                      }
  2264.                      else if (a == 0)
  2265.                      {
  2266.                         /* background is already in screen gamma */
  2267.                         *dp = (png_byte)((background->red >> 8) & 0xff);
  2268.                         *(dp + 1) = (png_byte)(background->red & 0xff);
  2269.                         *(dp + 2) = (png_byte)((background->green >> 8) & 0xff);
  2270.                         *(dp + 3) = (png_byte)(background->green & 0xff);
  2271.                         *(dp + 4) = (png_byte)((background->blue >> 8) & 0xff);
  2272.                         *(dp + 5) = (png_byte)(background->blue & 0xff);
  2273.                      }
  2274.                      else
  2275.                      {
  2276.                         png_uint_16 v, w, x;
  2277.  
  2278.                         v = gamma_16_to_1[*(sp + 1) >> gamma_shift][*sp];
  2279.                         png_composite_16(w, v, a, background->red);
  2280.                         x = gamma_16_from_1[((w&0xff) >> gamma_shift)][w >> 8];
  2281.                         *dp = (png_byte)((x >> 8) & 0xff);
  2282.                         *(dp + 1) = (png_byte)(x & 0xff);
  2283.                         v = gamma_16_to_1[*(sp + 3) >> gamma_shift][*(sp + 2)];
  2284.                         png_composite_16(w, v, a, background->green);
  2285.                         x = gamma_16_from_1[((w&0xff) >> gamma_shift)][w >> 8];
  2286.                         *(dp + 2) = (png_byte)((x >> 8) & 0xff);
  2287.                         *(dp + 3) = (png_byte)(x & 0xff);
  2288.                         v = gamma_16_to_1[*(sp + 5) >> gamma_shift][*(sp + 4)];
  2289.                         png_composite_16(w, v, a, background->blue);
  2290.                         x = gamma_16_from_1[(w & 0xff) >> gamma_shift][w >> 8];
  2291.                         *(dp + 4) = (png_byte)((x >> 8) & 0xff);
  2292.                         *(dp + 5) = (png_byte)(x & 0xff);
  2293.                      }
  2294.                   }
  2295.                }
  2296.                else
  2297. #endif
  2298.                {
  2299.                   for (i = 0, sp = row, dp = row;
  2300.                      i < row_info->width; i++, sp += 8, dp += 6)
  2301.                   {
  2302.                      png_uint_16 a;
  2303.  
  2304.                      a = (png_uint_16)(((png_uint_16)(*(sp + 6)) << 8) +
  2305.                         (png_uint_16)(*(sp + 7)));
  2306.                      if (a == (png_uint_16)0xffff)
  2307.                      {
  2308.                         png_memcpy(dp, sp, 6);
  2309.                      }
  2310.                      else if (a == 0)
  2311.                      {
  2312.                         *dp = (png_byte)((background->red >> 8) & 0xff);
  2313.                         *(dp + 1) = (png_byte)(background->red & 0xff);
  2314.                         *(dp + 2) = (png_byte)((background->green >> 8) & 0xff);
  2315.                         *(dp + 3) = (png_byte)(background->green & 0xff);
  2316.                         *(dp + 4) = (png_byte)((background->blue >> 8) & 0xff);
  2317.                         *(dp + 5) = (png_byte)(background->blue & 0xff);
  2318.                      }
  2319.                      else
  2320.                      {
  2321.                         png_uint_16 r, g, b, v;
  2322.  
  2323.                         r = ((png_uint_16)(*sp) << 8) + *(sp + 1);
  2324.                         g = ((png_uint_16)(*(sp + 2)) << 8) + *(sp + 3);
  2325.                         b = ((png_uint_16)(*(sp + 4)) << 8) + *(sp + 5);
  2326.  
  2327.                         png_composite_16(v, r, a, background->red);
  2328.                         *dp = (png_byte)((v >> 8) & 0xff);
  2329.                         *(dp + 1) = (png_byte)(v & 0xff);
  2330.                         png_composite_16(v, g, a, background->green);
  2331.                         *(dp + 2) = (png_byte)((v >> 8) & 0xff);
  2332.                         *(dp + 3) = (png_byte)(v & 0xff);
  2333.                         png_composite_16(v, g, a, background->green);
  2334.                         *(dp + 4) = (png_byte)((v >> 8) & 0xff);
  2335.                         *(dp + 5) = (png_byte)(v & 0xff);
  2336.                      }
  2337.                   }
  2338.                }
  2339.             }
  2340.             break;
  2341.          }
  2342.       }
  2343.  
  2344.       if (row_info->color_type & PNG_COLOR_MASK_ALPHA)
  2345.       {
  2346.          row_info->color_type &= ~PNG_COLOR_MASK_ALPHA;
  2347.          row_info->channels--;
  2348.          row_info->pixel_depth = (png_byte)(row_info->channels *
  2349.             row_info->bit_depth);
  2350.          row_info->rowbytes = (png_size_t)((row_info->width *
  2351.             row_info->pixel_depth + 7) >> 3);
  2352.       }
  2353.    }
  2354. }
  2355. #endif
  2356.  
  2357. #if defined(PNG_READ_GAMMA_SUPPORTED)
  2358. /* Gamma correct the image, avoiding the alpha channel.  Make sure
  2359.    you do this after you deal with the trasparency issue on grayscale
  2360.    or rgb images. If your bit depth is 8, use gamma_table, if it
  2361.    is 16, use gamma_16_table and gamma_shift.  Build these with
  2362.    build_gamma_table(). */
  2363. void
  2364. png_do_gamma(png_row_infop row_info, png_bytep row,
  2365.    png_bytep gamma_table, png_uint_16pp gamma_16_table,
  2366.    int gamma_shift)
  2367. {
  2368.    png_bytep sp;
  2369.    png_uint_32 i;
  2370.  
  2371.    png_debug(1, "in png_do_gamma\n");
  2372.    if (
  2373. #if defined(PNG_USELESS_TESTS_SUPPORTED)
  2374.        row != NULL && row_info != NULL &&
  2375. #endif
  2376.        ((row_info->bit_depth <= 8 && gamma_table != NULL) ||
  2377.         (row_info->bit_depth == 16 && gamma_16_table != NULL)))
  2378.    {
  2379.       switch (row_info->color_type)
  2380.       {
  2381.          case PNG_COLOR_TYPE_RGB:
  2382.          {
  2383.             if (row_info->bit_depth == 8)
  2384.             {
  2385.                for (i = 0, sp = row; i < row_info->width; i++)
  2386.                {
  2387.                   *sp = gamma_table[*sp];
  2388.                   sp++;
  2389.                   *sp = gamma_table[*sp];
  2390.                   sp++;
  2391.                   *sp = gamma_table[*sp];
  2392.                   sp++;
  2393.                }
  2394.             }
  2395.             else /* if (row_info->bit_depth == 16) */
  2396.             {
  2397.                for (i = 0, sp = row; i < row_info->width; i++)
  2398.                {
  2399.                   png_uint_16 v;
  2400.  
  2401.                   v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
  2402.                   *sp = (png_byte)((v >> 8) & 0xff);
  2403.                   *(sp + 1) = (png_byte)(v & 0xff);
  2404.                   sp += 2;
  2405.                   v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
  2406.                   *sp = (png_byte)((v >> 8) & 0xff);
  2407.                   *(sp + 1) = (png_byte)(v & 0xff);
  2408.                   sp += 2;
  2409.                   v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
  2410.                   *sp = (png_byte)((v >> 8) & 0xff);
  2411.                   *(sp + 1) = (png_byte)(v & 0xff);
  2412.                   sp += 2;
  2413.                }
  2414.             }
  2415.             break;
  2416.          }
  2417.          case PNG_COLOR_TYPE_RGB_ALPHA:
  2418.          {
  2419.             if (row_info->bit_depth == 8)
  2420.             {
  2421.                for (i = 0, sp = row;
  2422.                   i < row_info->width; i++)
  2423.                {
  2424.                   *sp = gamma_table[*sp];
  2425.                   sp++;
  2426.                   *sp = gamma_table[*sp];
  2427.                   sp++;
  2428.                   *sp = gamma_table[*sp];
  2429.                   sp++;
  2430.                   sp++;
  2431.                }
  2432.             }
  2433.             else /* if (row_info->bit_depth == 16) */
  2434.             {
  2435.                for (i = 0, sp = row;
  2436.                   i < row_info->width; i++)
  2437.                {
  2438.                   png_uint_16 v;
  2439.  
  2440.                   v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
  2441.                   *sp = (png_byte)((v >> 8) & 0xff);
  2442.                   *(sp + 1) = (png_byte)(v & 0xff);
  2443.                   sp += 2;
  2444.                   v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
  2445.                   *sp = (png_byte)((v >> 8) & 0xff);
  2446.                   *(sp + 1) = (png_byte)(v & 0xff);
  2447.                   sp += 2;
  2448.                   v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
  2449.                   *sp = (png_byte)((v >> 8) & 0xff);
  2450.                   *(sp + 1) = (png_byte)(v & 0xff);
  2451.                   sp += 4;
  2452.                }
  2453.             }
  2454.             break;
  2455.          }
  2456.          case PNG_COLOR_TYPE_GRAY_ALPHA:
  2457.          {
  2458.             if (row_info->bit_depth == 8)
  2459.             {
  2460.                for (i = 0, sp = row;
  2461.                   i < row_info->width; i++)
  2462.                {
  2463.                   *sp = gamma_table[*sp];
  2464.                   sp += 2;
  2465.                }
  2466.             }
  2467.             else /* if (row_info->bit_depth == 16) */
  2468.             {
  2469.                for (i = 0, sp = row;
  2470.                   i < row_info->width; i++)
  2471.                {
  2472.                   png_uint_16 v;
  2473.  
  2474.                   v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
  2475.                   *sp = (png_byte)((v >> 8) & 0xff);
  2476.                   *(sp + 1) = (png_byte)(v & 0xff);
  2477.                   sp += 4;
  2478.                }
  2479.             }
  2480.             break;
  2481.          }
  2482.          case PNG_COLOR_TYPE_GRAY:
  2483.          {
  2484.             if (row_info->bit_depth == 4)
  2485.             {
  2486.                for (i = 0, sp = row; i < row_info->width; i += 2)
  2487.                {
  2488.                   int msb = *sp & 0xf0;
  2489.                   int lsb = *sp & 0x0f;
  2490.  
  2491.                   *sp = (((int)gamma_table[msb | msb >> 4] + 8) & 0xf0) |
  2492.                         (((int)gamma_table[lsb << 4 | lsb] + 8) >> 4);
  2493.                   sp++;
  2494.                }
  2495.             }
  2496.             else if (row_info->bit_depth == 8)
  2497.             {
  2498.                for (i = 0, sp = row; i < row_info->width; i++)
  2499.                {
  2500.                   *sp = gamma_table[*sp];
  2501.                   sp++;
  2502.                }
  2503.             }
  2504.             else if (row_info->bit_depth == 16)
  2505.             {
  2506.                for (i = 0, sp = row; i < row_info->width; i++)
  2507.                {
  2508.                   png_uint_16 v;
  2509.  
  2510.                   v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
  2511.                   *sp = (png_byte)((v >> 8) & 0xff);
  2512.                   *(sp + 1) = (png_byte)(v & 0xff);
  2513.                   sp += 2;
  2514.                }
  2515.             }
  2516.             break;
  2517.          }
  2518.       }
  2519.    }
  2520. }
  2521. #endif
  2522.  
  2523. #if defined(PNG_READ_EXPAND_SUPPORTED)
  2524. /* expands a palette row to an rgb or rgba row depending
  2525.    upon whether you supply trans and num_trans */
  2526. void
  2527. png_do_expand_palette(png_row_infop row_info, png_bytep row,
  2528.    png_colorp palette, png_bytep trans, int num_trans)
  2529. {
  2530.    int shift, value;
  2531.    png_bytep sp, dp;
  2532.    png_uint_32 i;
  2533.  
  2534.    png_debug(1, "in png_do_expand_palette\n");
  2535.    if (
  2536. #if defined(PNG_USELESS_TESTS_SUPPORTED)
  2537.        row != NULL && row_info != NULL &&
  2538. #endif
  2539.        row_info->color_type == PNG_COLOR_TYPE_PALETTE)
  2540.    {
  2541.       if (row_info->bit_depth < 8)
  2542.       {
  2543.          switch (row_info->bit_depth)
  2544.          {
  2545.             case 1:
  2546.             {
  2547.                sp = row + (png_size_t)((row_info->width - 1) >> 3);
  2548.                dp = row + (png_size_t)row_info->width - 1;
  2549.                shift = 7 - (int)((row_info->width + 7) & 7);
  2550.                for (i = 0; i < row_info->width; i++)
  2551.                {
  2552.                   if ((*sp >> shift) & 0x1)
  2553.                      *dp = 1;
  2554.                   else
  2555.                      *dp = 0;
  2556.                   if (shift == 7)
  2557.                   {
  2558.                      shift = 0;
  2559.                      sp--;
  2560.                   }
  2561.                   else
  2562.                      shift++;
  2563.  
  2564.                   dp--;
  2565.                }
  2566.                break;
  2567.             }
  2568.             case 2:
  2569.             {
  2570.                sp = row + (png_size_t)((row_info->width - 1) >> 2);
  2571.                dp = row + (png_size_t)row_info->width - 1;
  2572.                shift = (int)((3 - ((row_info->width + 3) & 3)) << 1);
  2573.                for (i = 0; i < row_info->width; i++)
  2574.                {
  2575.                   value = (*sp >> shift) & 0x3;
  2576.                   *dp = (png_byte)value;
  2577.                   if (shift == 6)
  2578.                   {
  2579.                      shift = 0;
  2580.                      sp--;
  2581.                   }
  2582.                   else
  2583.                      shift += 2;
  2584.  
  2585.                   dp--;
  2586.                }
  2587.                break;
  2588.             }
  2589.             case 4:
  2590.             {
  2591.                sp = row + (png_size_t)((row_info->width - 1) >> 1);
  2592.                dp = row + (png_size_t)row_info->width - 1;
  2593.                shift = (int)((row_info->width & 1) << 2);
  2594.                for (i = 0; i < row_info->width; i++)
  2595.                {
  2596.                   value = (*sp >> shift) & 0xf;
  2597.                   *dp = (png_byte)value;
  2598.                   if (shift == 4)
  2599.                   {
  2600.                      shift = 0;
  2601.                      sp--;
  2602.                   }
  2603.                   else
  2604.                      shift += 4;
  2605.  
  2606.                   dp--;
  2607.                }
  2608.                break;
  2609.             }
  2610.          }
  2611.          row_info->bit_depth = 8;
  2612.          row_info->pixel_depth = 8;
  2613.          row_info->rowbytes = (png_size_t)row_info->width;
  2614.       }
  2615.       switch (row_info->bit_depth)
  2616.       {
  2617.          case 8:
  2618.          {
  2619.             if (trans != NULL)
  2620.             {
  2621.                sp = row + (png_size_t)row_info->width - 1;
  2622.                dp = row + (png_size_t)(row_info->width << 2) - 1;
  2623.  
  2624.                for (i = 0; i < row_info->width; i++)
  2625.                {
  2626.                   if ((int)(*sp) >= num_trans)
  2627.                      *dp-- = 0xff;
  2628.                   else
  2629.                      *dp-- = trans[*sp];
  2630.                   *dp-- = palette[*sp].blue;
  2631.                   *dp-- = palette[*sp].green;
  2632.                   *dp-- = palette[*sp].red;
  2633.                   sp--;
  2634.                }
  2635.                row_info->bit_depth = 8;
  2636.                row_info->pixel_depth = 32;
  2637.                row_info->rowbytes = (png_size_t)row_info->width * 4;
  2638.                row_info->color_type = 6;
  2639.                row_info->channels = 4;
  2640.             }
  2641.             else
  2642.             {
  2643.                sp = row + (png_size_t)row_info->width - 1;
  2644.                dp = row + (png_size_t)(row_info->width * 3) - 1;
  2645.  
  2646.                for (i = 0; i < row_info->width; i++)
  2647.                {
  2648.                   *dp-- = palette[*sp].blue;
  2649.                   *dp-- = palette[*sp].green;
  2650.                   *dp-- = palette[*sp].red;
  2651.                   sp--;
  2652.                }
  2653.                row_info->bit_depth = 8;
  2654.                row_info->pixel_depth = 24;
  2655.                row_info->rowbytes = (png_size_t)row_info->width * 3;
  2656.                row_info->color_type = 2;
  2657.                row_info->channels = 3;
  2658.             }
  2659.             break;
  2660.          }
  2661.       }
  2662.    }
  2663. }
  2664.  
  2665. /* if the bit depth < 8, it is expanded to 8.  Also, if the
  2666.    transparency value is supplied, an alpha channel is built. */
  2667. void
  2668. png_do_expand(png_row_infop row_info, png_bytep row,
  2669.    png_color_16p trans_value)
  2670. {
  2671.    int shift, value;
  2672.    png_bytep sp, dp;
  2673.    png_uint_32 i;
  2674.  
  2675.    png_debug(1, "in png_do_expand\n");
  2676. #if defined(PNG_USELESS_TESTS_SUPPORTED)
  2677.    if (row != NULL && row_info != NULL)
  2678. #endif
  2679.    {
  2680.       if (row_info->color_type == PNG_COLOR_TYPE_GRAY)
  2681.       {
  2682.          png_uint_16 gray = trans_value ? trans_value->gray : 0;
  2683.  
  2684.          if (row_info->bit_depth < 8)
  2685.          {
  2686.             switch (row_info->bit_depth)
  2687.             {
  2688.                case 1:
  2689.                {
  2690.                   gray *= 0xff;
  2691.                   sp = row + (png_size_t)((row_info->width - 1) >> 3);
  2692.                   dp = row + (png_size_t)row_info->width - 1;
  2693.                   shift = 7 - (int)((row_info->width + 7) & 7);
  2694.                   for (i = 0; i < row_info->width; i++)
  2695.                   {
  2696.                      if ((*sp >> shift) & 0x1)
  2697.                         *dp = 0xff;
  2698.                      else
  2699.                         *dp = 0;
  2700.                      if (shift == 7)
  2701.                      {
  2702.                         shift = 0;
  2703.                         sp--;
  2704.                      }
  2705.                      else
  2706.                         shift++;
  2707.  
  2708.                      dp--;
  2709.                   }
  2710.                   break;
  2711.                }
  2712.                case 2:
  2713.                {
  2714.                   gray *= 0x55;
  2715.                   sp = row + (png_size_t)((row_info->width - 1) >> 2);
  2716.                   dp = row + (png_size_t)row_info->width - 1;
  2717.                   shift = (int)((3 - ((row_info->width + 3) & 3)) << 1);
  2718.                   for (i = 0; i < row_info->width; i++)
  2719.                   {
  2720.                      value = (*sp >> shift) & 0x3;
  2721.                      *dp = (png_byte)(value | (value << 2) | (value << 4) |
  2722.                         (value << 6));
  2723.                      if (shift == 6)
  2724.                      {
  2725.                         shift = 0;
  2726.                         sp--;
  2727.                      }
  2728.                      else
  2729.                         shift += 2;
  2730.  
  2731.                      dp--;
  2732.                   }
  2733.                   break;
  2734.                }
  2735.                case 4:
  2736.                {
  2737.                   gray *= 0x11;
  2738.                   sp = row + (png_size_t)((row_info->width - 1) >> 1);
  2739.                   dp = row + (png_size_t)row_info->width - 1;
  2740.                   shift = (int)((1 - ((row_info->width + 1) & 1)) << 2);
  2741.                   for (i = 0; i < row_info->width; i++)
  2742.                   {
  2743.                      value = (*sp >> shift) & 0xf;
  2744.                      *dp = (png_byte)(value | (value << 4));
  2745.                      if (shift == 4)
  2746.                      {
  2747.                         shift = 0;
  2748.                         sp--;
  2749.                      }
  2750.                      else
  2751.                         shift = 4;
  2752.  
  2753.                      dp--;
  2754.                   }
  2755.                   break;
  2756.                }
  2757.             }
  2758.             row_info->bit_depth = 8;
  2759.             row_info->pixel_depth = 8;
  2760.             row_info->rowbytes = (png_size_t)row_info->width;
  2761.          }
  2762.  
  2763.          if (trans_value != NULL)
  2764.          {
  2765.             if (row_info->bit_depth == 8)
  2766.             {
  2767.                sp = row + (png_size_t)row_info->width - 1;
  2768.                dp = row + (png_size_t)(row_info->width << 1) - 1;
  2769.                for (i = 0; i < row_info->width; i++)
  2770.                {
  2771.                   if (*sp == gray)
  2772.                      *dp-- = 0;
  2773.                   else
  2774.                      *dp-- = 0xff;
  2775.                   *dp-- = *sp--;
  2776.                }
  2777.             }
  2778.             else if (row_info->bit_depth == 16)
  2779.             {
  2780.                sp = row + row_info->rowbytes - 1;
  2781.                dp = row + (row_info->rowbytes << 1) - 1;
  2782.                for (i = 0; i < row_info->width; i++)
  2783.                {
  2784.                   if (((png_uint_16)*(sp) |
  2785.                      ((png_uint_16)*(sp - 1) << 8)) == gray)
  2786.                   {
  2787.                      *dp-- = 0;
  2788.                      *dp-- = 0;
  2789.                   }
  2790.                   else
  2791.                   {
  2792.                      *dp-- = 0xff;
  2793.                      *dp-- = 0xff;
  2794.                   }
  2795.                   *dp-- = *sp--;
  2796.                   *dp-- = *sp--;
  2797.                }
  2798.             }
  2799.             row_info->color_type = PNG_COLOR_TYPE_GRAY_ALPHA;
  2800.             row_info->channels = 2;
  2801.             row_info->pixel_depth = (png_byte)(row_info->bit_depth << 1);
  2802.             row_info->rowbytes =
  2803.                (png_size_t)((row_info->width * row_info->pixel_depth) >> 3);
  2804.          }
  2805.       }
  2806.       else if (row_info->color_type == PNG_COLOR_TYPE_RGB && trans_value)
  2807.       {
  2808.          if (row_info->bit_depth == 8)
  2809.          {
  2810.             sp = row + (png_size_t)row_info->rowbytes - 1;
  2811.             dp = row + (png_size_t)(row_info->width << 2) - 1;
  2812.             for (i = 0; i < row_info->width; i++)
  2813.             {
  2814.                if (*(sp - 2) == trans_value->red &&
  2815.                   *(sp - 1) == trans_value->green &&
  2816.                   *(sp - 0) == trans_value->blue)
  2817.                   *dp-- = 0;
  2818.                else
  2819.                   *dp-- = 0xff;
  2820.                *dp-- = *sp--;
  2821.                *dp-- = *sp--;
  2822.                *dp-- = *sp--;
  2823.             }
  2824.          }
  2825.          else if (row_info->bit_depth == 16)
  2826.          {
  2827.             sp = row + row_info->rowbytes - 1;
  2828.             dp = row + (png_size_t)(row_info->width << 3) - 1;
  2829.             for (i = 0; i < row_info->width; i++)
  2830.             {
  2831.                if ((((png_uint_16)*(sp - 4) |
  2832.                   ((png_uint_16)*(sp - 5) << 8)) == trans_value->red) &&
  2833.                   (((png_uint_16)*(sp - 2) |
  2834.                   ((png_uint_16)*(sp - 3) << 8)) == trans_value->green) &&
  2835.                   (((png_uint_16)*(sp - 0) |
  2836.                   ((png_uint_16)*(sp - 1) << 8)) == trans_value->blue))
  2837.                {
  2838.                   *dp-- = 0;
  2839.                   *dp-- = 0;
  2840.                }
  2841.                else
  2842.                {
  2843.                   *dp-- = 0xff;
  2844.                   *dp-- = 0xff;
  2845.                }
  2846.                *dp-- = *sp--;
  2847.                *dp-- = *sp--;
  2848.                *dp-- = *sp--;
  2849.                *dp-- = *sp--;
  2850.                *dp-- = *sp--;
  2851.                *dp-- = *sp--;
  2852.             }
  2853.          }
  2854.          row_info->color_type = PNG_COLOR_TYPE_RGB_ALPHA;
  2855.          row_info->channels = 4;
  2856.          row_info->pixel_depth = (png_byte)(row_info->bit_depth << 2);
  2857.          row_info->rowbytes =
  2858.             (png_size_t)((row_info->width * row_info->pixel_depth) >> 3);
  2859.       }
  2860.    }
  2861. }
  2862. #endif
  2863.  
  2864. #if defined(PNG_READ_DITHER_SUPPORTED)
  2865. void
  2866. png_do_dither(png_row_infop row_info, png_bytep row,
  2867.     png_bytep palette_lookup, png_bytep dither_lookup)
  2868. {
  2869.    png_bytep sp, dp;
  2870.    png_uint_32 i;
  2871.  
  2872.    png_debug(1, "in png_do_dither\n");
  2873. #if defined(PNG_USELESS_TESTS_SUPPORTED)
  2874.    if (row != NULL && row_info != NULL)
  2875. #endif
  2876.    {
  2877.       if (row_info->color_type == PNG_COLOR_TYPE_RGB &&
  2878.          palette_lookup && row_info->bit_depth == 8)
  2879.       {
  2880.          int r, g, b, p;
  2881.          sp = row;
  2882.          dp = row;
  2883.          for (i = 0; i < row_info->width; i++)
  2884.          {
  2885.             r = *sp++;
  2886.             g = *sp++;
  2887.             b = *sp++;
  2888.  
  2889.             /* this looks real messy, but the compiler will reduce
  2890.                it down to a reasonable formula.  For example, with
  2891.                5 bits per color, we get:
  2892.                p = (((r >> 3) & 0x1f) << 10) |
  2893.                   (((g >> 3) & 0x1f) << 5) |
  2894.                   ((b >> 3) & 0x1f);
  2895.                */
  2896.             p = (((r >> (8 - PNG_DITHER_RED_BITS)) &
  2897.                ((1 << PNG_DITHER_RED_BITS) - 1)) <<
  2898.                (PNG_DITHER_GREEN_BITS + PNG_DITHER_BLUE_BITS)) |
  2899.                (((g >> (8 - PNG_DITHER_GREEN_BITS)) &
  2900.                ((1 << PNG_DITHER_GREEN_BITS) - 1)) <<
  2901.                (PNG_DITHER_BLUE_BITS)) |
  2902.                ((b >> (8 - PNG_DITHER_BLUE_BITS)) &
  2903.                ((1 << PNG_DITHER_BLUE_BITS) - 1));
  2904.  
  2905.             *dp++ = palette_lookup[p];
  2906.          }
  2907.          row_info->color_type = PNG_COLOR_TYPE_PALETTE;
  2908.          row_info->channels = 1;
  2909.          row_info->pixel_depth = row_info->bit_depth;
  2910.          row_info->rowbytes =
  2911.             ((row_info->width * row_info->pixel_depth + 7) >> 3);
  2912.       }
  2913.       else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA &&
  2914.          palette_lookup != NULL && row_info->bit_depth == 8)
  2915.       {
  2916.          int r, g, b, p;
  2917.          sp = row;
  2918.          dp = row;
  2919.          for (i = 0; i < row_info->width; i++)
  2920.          {
  2921.             r = *sp++;
  2922.             g = *sp++;
  2923.             b = *sp++;
  2924.             sp++;
  2925.  
  2926.             p = (((r >> (8 - PNG_DITHER_RED_BITS)) &
  2927.                ((1 << PNG_DITHER_RED_BITS) - 1)) <<
  2928.                (PNG_DITHER_GREEN_BITS + PNG_DITHER_BLUE_BITS)) |
  2929.                (((g >> (8 - PNG_DITHER_GREEN_BITS)) &
  2930.                ((1 << PNG_DITHER_GREEN_BITS) - 1)) <<
  2931.                (PNG_DITHER_BLUE_BITS)) |
  2932.                ((b >> (8 - PNG_DITHER_BLUE_BITS)) &
  2933.                ((1 << PNG_DITHER_BLUE_BITS) - 1));
  2934.  
  2935.             *dp++ = palette_lookup[p];
  2936.          }
  2937.          row_info->color_type = PNG_COLOR_TYPE_PALETTE;
  2938.          row_info->channels = 1;
  2939.          row_info->pixel_depth = row_info->bit_depth;
  2940.          row_info->rowbytes =
  2941.             (png_size_t)((row_info->width * row_info->pixel_depth + 7) >> 3);
  2942.       }
  2943.       else if (row_info->color_type == PNG_COLOR_TYPE_PALETTE &&
  2944.          dither_lookup && row_info->bit_depth == 8)
  2945.       {
  2946.          sp = row;
  2947.          for (i = 0; i < row_info->width; i++, sp++)
  2948.          {
  2949.             *sp = dither_lookup[*sp];
  2950.          }
  2951.       }
  2952.    }
  2953. }
  2954. #endif
  2955.  
  2956. #if defined(PNG_READ_GAMMA_SUPPORTED)
  2957. static int png_gamma_shift[] =
  2958.    {0x10, 0x21, 0x42, 0x84, 0x110, 0x248, 0x550, 0xff0};
  2959.  
  2960. /* We build the 8- or 16-bit gamma tables here.  Note that for 16-bit
  2961.    tables, we don't make a full table if we are reducing to 8-bit in
  2962.    the future.  Note also how the gamma_16 tables are segmented so that
  2963.    we don't need to allocate > 64K chunks for a full 16-bit table. */
  2964. void
  2965. png_build_gamma_table(png_structp png_ptr)
  2966. {
  2967.    png_debug(1, "in png_build_gamma_table\n");
  2968.    if (png_ptr->bit_depth <= 8)
  2969.    {
  2970.       int i;
  2971.       double g;
  2972.  
  2973.       g = 1.0 / (png_ptr->gamma * png_ptr->display_gamma);
  2974.  
  2975.       png_ptr->gamma_table = (png_bytep)png_malloc(png_ptr,
  2976.          (png_uint_32)256);
  2977.  
  2978.       for (i = 0; i < 256; i++)
  2979.       {
  2980.          png_ptr->gamma_table[i] = (png_byte)(pow((double)i / 255.0,
  2981.             g) * 255.0 + .5);
  2982.       }
  2983.  
  2984. #if defined(PNG_READ_BACKGROUND_SUPPORTED)
  2985.       if (png_ptr->transformations & PNG_BACKGROUND)
  2986.       {
  2987.          g = 1.0 / (png_ptr->gamma);
  2988.  
  2989.          png_ptr->gamma_to_1 = (png_bytep)png_malloc(png_ptr,
  2990.             (png_uint_32)256);
  2991.  
  2992.          for (i = 0; i < 256; i++)
  2993.          {
  2994.             png_ptr->gamma_to_1[i] = (png_byte)(pow((double)i / 255.0,
  2995.                g) * 255.0 + .5);
  2996.          }
  2997.  
  2998.          g = 1.0 / (png_ptr->display_gamma);
  2999.  
  3000.          png_ptr->gamma_from_1 = (png_bytep)png_malloc(png_ptr,
  3001.             (png_uint_32)256);
  3002.  
  3003.          for (i = 0; i < 256; i++)
  3004.          {
  3005.             png_ptr->gamma_from_1[i] = (png_byte)(pow((double)i / 255.0,
  3006.                g) * 255.0 + .5);
  3007.          }
  3008.       }
  3009. #endif /* PNG_BACKGROUND_SUPPORTED */
  3010.    }
  3011.    else
  3012.    {
  3013.       double g;
  3014.       int i, j, shift, num;
  3015.       int sig_bit;
  3016.       png_uint_32 ig;
  3017.  
  3018.       if (png_ptr->color_type & PNG_COLOR_MASK_COLOR)
  3019.       {
  3020.          sig_bit = (int)png_ptr->sig_bit.red;
  3021.          if ((int)png_ptr->sig_bit.green > sig_bit)
  3022.             sig_bit = png_ptr->sig_bit.green;
  3023.          if ((int)png_ptr->sig_bit.blue > sig_bit)
  3024.             sig_bit = png_ptr->sig_bit.blue;
  3025.       }
  3026.       else
  3027.       {
  3028.          sig_bit = (int)png_ptr->sig_bit.gray;
  3029.       }
  3030.  
  3031.       if (sig_bit > 0)
  3032.          shift = 16 - sig_bit;
  3033.       else
  3034.          shift = 0;
  3035.  
  3036.       if (png_ptr->transformations & PNG_16_TO_8)
  3037.       {
  3038.          if (shift < (16 - PNG_MAX_GAMMA_8))
  3039.             shift = (16 - PNG_MAX_GAMMA_8);
  3040.       }
  3041.  
  3042.       if (shift > 8)
  3043.          shift = 8;
  3044.       if (shift < 0)
  3045.          shift = 0;
  3046.  
  3047.       png_ptr->gamma_shift = (png_byte)shift;
  3048.  
  3049.       num = (1 << (8 - shift));
  3050.  
  3051.       g = 1.0 / (png_ptr->gamma * png_ptr->display_gamma);
  3052.  
  3053.       png_ptr->gamma_16_table = (png_uint_16pp)png_malloc(png_ptr,
  3054.          num * sizeof (png_uint_16p));
  3055.  
  3056.       if ((png_ptr->transformations & PNG_16_TO_8) &&
  3057.          !(png_ptr->transformations & PNG_BACKGROUND))
  3058.       {
  3059.          double fin, fout;
  3060.          png_uint_32 last, max;
  3061.  
  3062.          for (i = 0; i < num; i++)
  3063.          {
  3064.             png_ptr->gamma_16_table[i] = (png_uint_16p)png_malloc(png_ptr,
  3065.                256 * sizeof (png_uint_16));
  3066.          }
  3067.  
  3068.          g = 1.0 / g;
  3069.          last = 0;
  3070.          for (i = 0; i < 256; i++)
  3071.          {
  3072.             fout = ((double)i + 0.5) / 256.0;
  3073.             fin = pow(fout, g);
  3074.             max = (png_uint_32)(fin * (double)((png_uint_32)num << 8));
  3075.             while (last <= max)
  3076.             {
  3077.                png_ptr->gamma_16_table[(int)(last & (0xff >> shift))]
  3078.                   [(int)(last >> (8 - shift))] = (png_uint_16)(
  3079.                   (png_uint_16)i | ((png_uint_16)i << 8));
  3080.                last++;
  3081.             }
  3082.          }
  3083.          while (last < ((png_uint_32)num << 8))
  3084.          {
  3085.             png_ptr->gamma_16_table[(int)(last & (0xff >> shift))]
  3086.                [(int)(last >> (8 - shift))] = (png_uint_16)65535L;
  3087.             last++;
  3088.          }
  3089.       }
  3090.       else
  3091.       {
  3092.          for (i = 0; i < num; i++)
  3093.          {
  3094.             png_ptr->gamma_16_table[i] = (png_uint_16p)png_malloc(png_ptr,
  3095.                256 * sizeof (png_uint_16));
  3096.  
  3097.             ig = (((png_uint_32)i * (png_uint_32)png_gamma_shift[shift]) >> 4);
  3098.             for (j = 0; j < 256; j++)
  3099.             {
  3100.                png_ptr->gamma_16_table[i][j] =
  3101.                   (png_uint_16)(pow((double)(ig + ((png_uint_32)j << 8)) /
  3102.                      65535.0, g) * 65535.0 + .5);
  3103.             }
  3104.          }
  3105.       }
  3106.  
  3107. #if defined(PNG_READ_BACKGROUND_SUPPORTED)
  3108.       if (png_ptr->transformations & PNG_BACKGROUND)
  3109.       {
  3110.          g = 1.0 / (png_ptr->gamma);
  3111.  
  3112.          png_ptr->gamma_16_to_1 = (png_uint_16pp)png_malloc(png_ptr,
  3113.             num * sizeof (png_uint_16p ));
  3114.  
  3115.          for (i = 0; i < num; i++)
  3116.          {
  3117.             png_ptr->gamma_16_to_1[i] = (png_uint_16p)png_malloc(png_ptr,
  3118.                256 * sizeof (png_uint_16));
  3119.  
  3120.             ig = (((png_uint_32)i *
  3121.                (png_uint_32)png_gamma_shift[shift]) >> 4);
  3122.             for (j = 0; j < 256; j++)
  3123.             {
  3124.                png_ptr->gamma_16_to_1[i][j] =
  3125.                   (png_uint_16)(pow((double)(ig + ((png_uint_32)j << 8)) /
  3126.                      65535.0, g) * 65535.0 + .5);
  3127.             }
  3128.          }
  3129.          g = 1.0 / (png_ptr->display_gamma);
  3130.  
  3131.          png_ptr->gamma_16_from_1 = (png_uint_16pp)png_malloc(png_ptr,
  3132.             num * sizeof (png_uint_16p));
  3133.  
  3134.          for (i = 0; i < num; i++)
  3135.          {
  3136.             png_ptr->gamma_16_from_1[i] = (png_uint_16p)png_malloc(png_ptr,
  3137.                256 * sizeof (png_uint_16));
  3138.  
  3139.             ig = (((png_uint_32)i *
  3140.                (png_uint_32)png_gamma_shift[shift]) >> 4);
  3141.             for (j = 0; j < 256; j++)
  3142.             {
  3143.                png_ptr->gamma_16_from_1[i][j] =
  3144.                   (png_uint_16)(pow((double)(ig + ((png_uint_32)j << 8)) /
  3145.                      65535.0, g) * 65535.0 + .5);
  3146.             }
  3147.          }
  3148.       }
  3149. #endif /* PNG_BACKGROUND_SUPPORTED */
  3150.    }
  3151. }
  3152. #endif
  3153.  
  3154.